Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-01 03:09:48 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-01 03:09:48 +0300
commit516b939c44ec77bb773f08df15079c80fb4d10d2 (patch)
tree7fa7670a0cd811df23d8a6b07e6473fa540ebe0f
parent9877050db1dd1693c672a6b29a356c5b2a7edce0 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/merge_request_templates/New End To End Test.md5
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/controllers/projects/pipelines_controller.rb5
-rw-r--r--app/graphql/types/ci/runner_upgrade_status_type_enum.rb4
-rw-r--r--app/models/ci/runner_version.rb29
-rw-r--r--app/models/user.rb4
-rw-r--r--config/initializers/1_acts_as_taggable.rb33
-rw-r--r--config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml5
-rw-r--r--config/metrics/counts_28d/20220622084700_p_analytics_ci_cd_time_to_restore_service_monthly.yml26
-rw-r--r--config/metrics/counts_7d/20220622084654_p_analytics_ci_cd_time_to_restore_service_weekly.yml26
-rw-r--r--db/docs/ci_runner_versions.yml9
-rw-r--r--db/migrate/20220624081524_add_ci_runner_versions_table.rb16
-rw-r--r--db/migrate/20220624090458_add_index_on_runner_version.rb15
-rw-r--r--db/schema_migrations/202206240815241
-rw-r--r--db/schema_migrations/202206240904581
-rw-r--r--db/structure.sql15
-rw-r--r--doc/administration/logs.md18
-rw-r--r--doc/development/i18n/externalization.md50
-rw-r--r--doc/development/testing_guide/end_to_end/resources.md10
-rw-r--r--doc/user/application_security/dependency_scanning/index.md7
-rw-r--r--lib/gitlab/ci/config/external/file/project.rb12
-rw-r--r--lib/gitlab/ci/runner_upgrade_check.rb7
-rw-r--r--lib/gitlab/database/gitlab_schemas.yml1
-rw-r--r--lib/gitlab/usage_data_counters/known_events/analytics.yml20
-rw-r--r--locale/gitlab.pot9
-rw-r--r--qa/qa/tools/test_resources_handler.rb3
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb4
-rw-r--r--spec/factories/ci/runner_versions.rb7
-rw-r--r--spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb9
-rw-r--r--spec/initializers/1_acts_as_taggable_spec.rb64
-rw-r--r--spec/lib/gitlab/ci/config/external/file/project_spec.rb16
-rw-r--r--spec/models/ci/runner_spec.rb40
-rw-r--r--spec/models/ci/runner_version_spec.rb26
-rw-r--r--spec/models/user_spec.rb56
34 files changed, 498 insertions, 57 deletions
diff --git a/.gitlab/merge_request_templates/New End To End Test.md b/.gitlab/merge_request_templates/New End To End Test.md
index 4c42b324553..46ccdb1cb0c 100644
--- a/.gitlab/merge_request_templates/New End To End Test.md
+++ b/.gitlab/merge_request_templates/New End To End Test.md
@@ -10,7 +10,10 @@ Please link to the respective test case in the testcases project
- [ ] Note if the test is intended to run in specific scenarios. If a scenario is new, add a link to the MR that adds the new scenario.
- [ ] Follow the end-to-end tests [style guide](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/style_guide.html) and [best practices](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/best_practices.html).
- [ ] Use the appropriate [RSpec metadata tag(s)](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/rspec_metadata_tests.html#rspec-metadata-for-end-to-end-tests).
-- [ ] Ensure that a created resource is removed after test execution. A `Group` resource can be shared between multiple tests. Do not remove it unless it has a unique path. Note that we have a cleanup job that periodically removes groups under `gitlab-qa-sandbox-group`.
+- Most resources will be cleaned up via the general [cleanup task](https://gitlab.com/gitlab-org/gitlab/-/blob/44345381e89d6bbd440f7b4c680d03e8b75b86de/qa/qa/tools/test_resources_handler.rb#L44). Check that is successful, or ensure resources are cleaned up in the test:
+ - [ ] New resources have `api_get_path` and `api_delete_path` implemented if possible.
+ - [ ] If any resource cannot be deleted in the general delete task, make sure it is [ignored](https://gitlab.com/gitlab-org/gitlab/-/blob/44345381e89d6bbd440f7b4c680d03e8b75b86de/qa/qa/tools/test_resources_handler.rb#L29).
+ - [ ] If any resource cannot be deleted in the general delete task, remove it in the test (e.g., in an `after` block).
- [ ] Ensure that no [transient bugs](https://about.gitlab.com/handbook/engineering/quality/issue-triage/#transient-bugs) are hidden accidentally due to the usage of `waits` and `reloads`.
- [ ] Verify the tags to ensure it runs on the desired test environments.
- [ ] If this MR has a dependency on another MR, such as a GitLab QA MR, specify the order in which the MRs should be merged.
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index e9517fdb50c..208c7a3ab24 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-c54d613d0eb9c573d79f5da0975655f11f007932
+0c72a4ba3de2125098d72fce52b99df3d4ad5475
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index adc3a912a91..976241a5149 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -38,6 +38,7 @@ class Projects::PipelinesController < Projects::ApplicationController
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_pipelines', if: -> { should_track_ci_cd_pipelines? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', if: -> { should_track_ci_cd_deployment_frequency? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_lead_time', if: -> { should_track_ci_cd_lead_time? }
+ track_redis_hll_event :charts, name: 'p_analytics_ci_cd_time_to_restore_service', if: -> { should_track_ci_cd_time_to_restore_service? }
wrap_parameters Ci::Pipeline
@@ -361,6 +362,10 @@ class Projects::PipelinesController < Projects::ApplicationController
def should_track_ci_cd_lead_time?
params[:chart] == 'lead-time'
end
+
+ def should_track_ci_cd_time_to_restore_service?
+ params[:chart] == 'time-to-restore-service'
+ end
end
Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController')
diff --git a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb b/app/graphql/types/ci/runner_upgrade_status_type_enum.rb
index 02feafe3df9..7c52ab5562a 100644
--- a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb
+++ b/app/graphql/types/ci/runner_upgrade_status_type_enum.rb
@@ -5,9 +5,9 @@ module Types
class RunnerUpgradeStatusTypeEnum < BaseEnum
graphql_name 'CiRunnerUpgradeStatusType'
- value 'UNKNOWN', description: 'Upgrade status is unknown.', value: :unknown
+ ::Ci::RunnerVersion::STATUS_DESCRIPTIONS.each do |status, description|
+ status = :invalid if status == :invalid_version
- Gitlab::Ci::RunnerUpgradeCheck::STATUSES.each do |status, description|
value status.to_s.upcase, description: description, value: status
end
end
diff --git a/app/models/ci/runner_version.rb b/app/models/ci/runner_version.rb
new file mode 100644
index 00000000000..ddbfad08cbb
--- /dev/null
+++ b/app/models/ci/runner_version.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Ci
+ class RunnerVersion < Ci::ApplicationRecord
+ include EnumWithNil
+
+ enum_with_nil status: {
+ not_processed: nil,
+ invalid_version: -1,
+ unknown: 0,
+ not_available: 1,
+ available: 2,
+ recommended: 3
+ }
+
+ STATUS_DESCRIPTIONS = {
+ invalid_version: 'Runner version is not valid.',
+ unknown: 'Upgrade status is unknown.',
+ not_available: 'Upgrade is not available for the runner.',
+ available: 'Upgrade is available for the runner.',
+ recommended: 'Upgrade is available and recommended for the runner.'
+ }.freeze
+
+ # Override auto generated negative scope (from available) so the scope has expected behavior
+ scope :not_available, -> { where(status: :not_available) }
+
+ validates :version, length: { maximum: 2048 }
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 40096dfa411..b35036d0af7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -476,8 +476,8 @@ class User < ApplicationRecord
end
scope :order_recent_sign_in, -> { reorder(arel_table[:current_sign_in_at].desc.nulls_last) }
scope :order_oldest_sign_in, -> { reorder(arel_table[:current_sign_in_at].asc.nulls_last) }
- scope :order_recent_last_activity, -> { reorder(arel_table[:last_activity_on].desc.nulls_last) }
- scope :order_oldest_last_activity, -> { reorder(arel_table[:last_activity_on].asc.nulls_first) }
+ scope :order_recent_last_activity, -> { reorder(arel_table[:last_activity_on].desc.nulls_last, arel_table[:id].asc) }
+ scope :order_oldest_last_activity, -> { reorder(arel_table[:last_activity_on].asc.nulls_first, arel_table[:id].desc) }
scope :by_id_and_login, ->(id, login) { where(id: id).where('username = LOWER(:login) OR email = LOWER(:login)', login: login) }
scope :dormant, -> { with_state(:active).human_or_service_user.where('last_activity_on <= ?', MINIMUM_INACTIVE_DAYS.day.ago.to_date) }
scope :with_no_activity, -> { with_state(:active).human_or_service_user.where(last_activity_on: nil).where('created_at <= ?', MINIMUM_DAYS_CREATED.day.ago.to_date) }
diff --git a/config/initializers/1_acts_as_taggable.rb b/config/initializers/1_acts_as_taggable.rb
index 59412aef755..0c34bf3941b 100644
--- a/config/initializers/1_acts_as_taggable.rb
+++ b/config/initializers/1_acts_as_taggable.rb
@@ -15,3 +15,36 @@ raise "Counter cache is not disabled" if
model.connection_specification_name = Ci::ApplicationRecord.connection_specification_name
model.singleton_class.delegate :connection, :sticking, to: '::Ci::ApplicationRecord'
end
+
+# Modified from https://github.com/mbleigh/acts-as-taggable-on/pull/1081
+# with insert_all, which is not supported in MySQL
+# See https://gitlab.com/gitlab-org/gitlab/-/issues/338346#note_996969960
+module ActsAsTaggableOnTagPatch
+ def find_or_create_all_with_like_by_name(*list)
+ list = Array(list).flatten
+
+ return [] if list.empty?
+
+ existing_tags = named_any(list)
+
+ missing = list.reject do |tag_name|
+ comparable_tag_name = comparable_name(tag_name)
+ existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name }
+ end
+
+ if missing.empty?
+ new_tags = []
+ else
+ attributes_to_add = missing.map do |tag_name|
+ { name: tag_name }
+ end
+
+ insert_all(attributes_to_add, unique_by: :name)
+ new_tags = named_any(missing)
+ end
+
+ existing_tags + new_tags
+ end
+end
+
+::ActsAsTaggableOn::Tag.singleton_class.prepend(ActsAsTaggableOnTagPatch)
diff --git a/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml b/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml
index ceb185c7108..c8cb9693a7f 100644
--- a/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml
+++ b/config/metrics/counts_28d/20210216174910_analytics_unique_visits_for_any_target_monthly.yml
@@ -33,6 +33,11 @@ options:
- p_analytics_ci_cd_pipelines
- p_analytics_ci_cd_deployment_frequency
- p_analytics_ci_cd_lead_time
+ - p_analytics_ci_cd_time_to_restore_service
+ - g_analytics_ci_cd_release_statistics
+ - g_analytics_ci_cd_deployment_frequency
+ - g_analytics_ci_cd_lead_time
+ - g_analytics_ci_cd_time_to_restore_service
distribution:
- ce
- ee
diff --git a/config/metrics/counts_28d/20220622084700_p_analytics_ci_cd_time_to_restore_service_monthly.yml b/config/metrics/counts_28d/20220622084700_p_analytics_ci_cd_time_to_restore_service_monthly.yml
new file mode 100644
index 00000000000..a9a62b1aa79
--- /dev/null
+++ b/config/metrics/counts_28d/20220622084700_p_analytics_ci_cd_time_to_restore_service_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.analytics.p_analytics_ci_cd_time_to_restore_service_monthly
+name: p_analytics_ci_cd_time_to_restore_service_monthly
+description: Count of unique visits to the project level CI/CD Analytics Time to restore service tab
+product_section: dev
+product_stage: manage
+product_group: optimize
+product_category:
+value_type: number
+status: active
+milestone: "15.2"
+introduced_by_url:
+time_frame: 28d
+data_source: redis_hll
+data_category: operational
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- premium
+- ultimate
+options:
+ events:
+ - p_analytics_ci_cd_time_to_restore_service
diff --git a/config/metrics/counts_7d/20220622084654_p_analytics_ci_cd_time_to_restore_service_weekly.yml b/config/metrics/counts_7d/20220622084654_p_analytics_ci_cd_time_to_restore_service_weekly.yml
new file mode 100644
index 00000000000..681fed23d11
--- /dev/null
+++ b/config/metrics/counts_7d/20220622084654_p_analytics_ci_cd_time_to_restore_service_weekly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.analytics.p_analytics_ci_cd_time_to_restore_service_weekly
+name: p_analytics_ci_cd_time_to_restore_service_weekly
+description: Count of unique visits to the project level CI/CD Analytics Time to restore service tab
+product_section: dev
+product_stage: manage
+product_group: optimize
+product_category:
+value_type: number
+status: active
+milestone: "15.2"
+introduced_by_url:
+time_frame: 7d
+data_source: redis_hll
+data_category: operational
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- premium
+- ultimate
+options:
+ events:
+ - p_analytics_ci_cd_time_to_restore_service
diff --git a/db/docs/ci_runner_versions.yml b/db/docs/ci_runner_versions.yml
new file mode 100644
index 00000000000..e0221e3956f
--- /dev/null
+++ b/db/docs/ci_runner_versions.yml
@@ -0,0 +1,9 @@
+---
+table_name: ci_runner_versions
+classes:
+- Ci::RunnerVersion
+feature_categories:
+- runner_fleet
+description: Information about used Ci::Runner versions
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90982
+milestone: '15.2'
diff --git a/db/migrate/20220624081524_add_ci_runner_versions_table.rb b/db/migrate/20220624081524_add_ci_runner_versions_table.rb
new file mode 100644
index 00000000000..844c5898d75
--- /dev/null
+++ b/db/migrate/20220624081524_add_ci_runner_versions_table.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddCiRunnerVersionsTable < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def up
+ create_table :ci_runner_versions, id: false do |t|
+ t.text :version, primary_key: true, index: true, null: false, limit: 2048
+ t.integer :status, null: true, limit: 2, index: true
+ end
+ end
+
+ def down
+ drop_table :ci_runner_versions, if_exists: true
+ end
+end
diff --git a/db/migrate/20220624090458_add_index_on_runner_version.rb b/db/migrate/20220624090458_add_index_on_runner_version.rb
new file mode 100644
index 00000000000..e28bf0d8a76
--- /dev/null
+++ b/db/migrate/20220624090458_add_index_on_runner_version.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexOnRunnerVersion < Gitlab::Database::Migration[2.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_ci_runners_on_version'
+
+ def up
+ add_concurrent_index :ci_runners, :version, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_runners, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20220624081524 b/db/schema_migrations/20220624081524
new file mode 100644
index 00000000000..f643b1223a8
--- /dev/null
+++ b/db/schema_migrations/20220624081524
@@ -0,0 +1 @@
+3245905956e4781629bbf6398c9534cf35eab469e8a703f755ed26de90dee0e1 \ No newline at end of file
diff --git a/db/schema_migrations/20220624090458 b/db/schema_migrations/20220624090458
new file mode 100644
index 00000000000..62473bf8bd3
--- /dev/null
+++ b/db/schema_migrations/20220624090458
@@ -0,0 +1 @@
+cf3c6e8d720ce48272b8b9658d3c240e8fe3c9a26284a9e169f7bb6a40c862bc \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 78ba17044d4..e511bd88618 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -13080,6 +13080,12 @@ CREATE SEQUENCE ci_runner_projects_id_seq
ALTER SEQUENCE ci_runner_projects_id_seq OWNED BY ci_runner_projects.id;
+CREATE TABLE ci_runner_versions (
+ version text NOT NULL,
+ status smallint,
+ CONSTRAINT check_b5a3714594 CHECK ((char_length(version) <= 2048))
+);
+
CREATE TABLE ci_runners (
id integer NOT NULL,
token character varying,
@@ -24577,6 +24583,9 @@ ALTER TABLE ONLY ci_runner_namespaces
ALTER TABLE ONLY ci_runner_projects
ADD CONSTRAINT ci_runner_projects_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_runner_versions
+ ADD CONSTRAINT ci_runner_versions_pkey PRIMARY KEY (version);
+
ALTER TABLE ONLY ci_runners
ADD CONSTRAINT ci_runners_pkey PRIMARY KEY (id);
@@ -27633,6 +27642,10 @@ CREATE UNIQUE INDEX index_ci_runner_namespaces_on_runner_id_and_namespace_id ON
CREATE INDEX index_ci_runner_projects_on_project_id ON ci_runner_projects USING btree (project_id);
+CREATE INDEX index_ci_runner_versions_on_status ON ci_runner_versions USING btree (status);
+
+CREATE INDEX index_ci_runner_versions_on_version ON ci_runner_versions USING btree (version);
+
CREATE INDEX index_ci_runners_on_active ON ci_runners USING btree (active, id);
CREATE INDEX index_ci_runners_on_contacted_at_and_id_desc ON ci_runners USING btree (contacted_at, id DESC);
@@ -27663,6 +27676,8 @@ CREATE INDEX index_ci_runners_on_token_expires_at_and_id_desc ON ci_runners USIN
CREATE INDEX index_ci_runners_on_token_expires_at_desc_and_id_desc ON ci_runners USING btree (token_expires_at DESC, id DESC);
+CREATE INDEX index_ci_runners_on_version ON ci_runners USING btree (version);
+
CREATE UNIQUE INDEX index_ci_running_builds_on_build_id ON ci_running_builds USING btree (build_id);
CREATE INDEX index_ci_running_builds_on_project_id ON ci_running_builds USING btree (project_id);
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 5a2c1190896..671c264ed85 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -1063,23 +1063,23 @@ For Omnibus GitLab installations, Mattermost logs are in these locations:
## Workhorse Logs
-For Omnibus GitLab installations, Workhorse logs are in `/var/log/gitlab/gitlab-workhorse/`.
+For Omnibus GitLab installations, Workhorse logs are in `/var/log/gitlab/gitlab-workhorse/current`.
## PostgreSQL Logs
-For Omnibus GitLab installations, PostgreSQL logs are in `/var/log/gitlab/postgresql/`.
+For Omnibus GitLab installations, PostgreSQL logs are in `/var/log/gitlab/postgresql/current`.
## Prometheus Logs
-For Omnibus GitLab installations, Prometheus logs are in `/var/log/gitlab/prometheus/`.
+For Omnibus GitLab installations, Prometheus logs are in `/var/log/gitlab/prometheus/current`.
## Redis Logs
-For Omnibus GitLab installations, Redis logs are in `/var/log/gitlab/redis/`.
+For Omnibus GitLab installations, Redis logs are in `/var/log/gitlab/redis/current`.
## Alertmanager Logs
-For Omnibus GitLab installations, Alertmanager logs are in `/var/log/gitlab/alertmanager/`.
+For Omnibus GitLab installations, Alertmanager logs are in `/var/log/gitlab/alertmanager/current`.
<!-- vale gitlab.Spelling = NO -->
@@ -1091,11 +1091,11 @@ For Omnibus GitLab installations, crond logs are in `/var/log/gitlab/crond/`.
## Grafana Logs
-For Omnibus GitLab installations, Grafana logs are in `/var/log/gitlab/grafana/`.
+For Omnibus GitLab installations, Grafana logs are in `/var/log/gitlab/grafana/current`.
## LogRotate Logs
-For Omnibus GitLab installations, `logrotate` logs are in `/var/log/gitlab/logrotate/`.
+For Omnibus GitLab installations, `logrotate` logs are in `/var/log/gitlab/logrotate/current`.
## GitLab Monitor Logs
@@ -1103,12 +1103,12 @@ For Omnibus GitLab installations, GitLab Monitor logs are in `/var/log/gitlab/gi
## GitLab Exporter
-For Omnibus GitLab installations, GitLab Exporter logs are in `/var/log/gitlab/gitlab-exporter/`.
+For Omnibus GitLab installations, GitLab Exporter logs are in `/var/log/gitlab/gitlab-exporter/current`.
## GitLab agent server
For Omnibus GitLab installations, GitLab agent server logs are
-in `/var/log/gitlab/gitlab-kas/`.
+in `/var/log/gitlab/gitlab-kas/current`.
## Praefect Logs
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index 2aea15de443..18704fc2b60 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -411,6 +411,56 @@ use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make sure to
// => When x == 2: 'Last 2 days'
```
+- In Vue:
+
+ One of [the recommended ways to organize translated strings for Vue files](#vue-files) is to extract them into a `constants.js` file.
+ That can be difficult to do when there are pluralized strings because the `count` variable won't be known inside the constants file.
+ To overcome this, we recommend creating a function which takes a `count` argument:
+
+ ```javascript
+ // .../feature/constants.js
+ import { n__ } from '~/locale';
+
+ export const I18N = {
+ // Strings that are only singular don't need to be a function
+ someDaysRemain: __('Some days remain'),
+ daysRemaining(count) { return n__('%d day remaining', '%d days remaining', count); },
+ };
+ ```
+
+ Then within a Vue component the function can be used to retrieve the correct pluralization form of the string:
+
+ ```javascript
+ // .../feature/components/days_remaining.vue
+ import { sprintf } from '~/locale';
+ import { I18N } from '../constants';
+
+ <script>
+ export default {
+ props: {
+ days: {
+ type: Number,
+ required: true,
+ },
+ },
+ i18n: I18N,
+ };
+ </script>
+
+ <template>
+ <div>
+ <span>
+ A singular string:
+ {{ $options.i18n.someDaysRemain }}
+ </span>
+ <span>
+ A plural string:
+ {{ $options.i18n.daysRemaining(days) }}
+ </span>
+ </div>
+ </template>
+ ```
+
The `n_` and `n__` methods should only be used to fetch pluralized translations of the same
string, not to control the logic of showing different strings for different
quantities. Some languages have different quantities of target plural forms.
diff --git a/doc/development/testing_guide/end_to_end/resources.md b/doc/development/testing_guide/end_to_end/resources.md
index dacc428aec6..a7626d372a8 100644
--- a/doc/development/testing_guide/end_to_end/resources.md
+++ b/doc/development/testing_guide/end_to_end/resources.md
@@ -568,6 +568,16 @@ def unique_identifiers
end
```
+### Resources cleanup
+
+We have a mechanism to [collect](https://gitlab.com/gitlab-org/gitlab/-/blob/44345381e89d6bbd440f7b4c680d03e8b75b86de/qa/qa/tools/test_resource_data_processor.rb#L32)
+all resources created during test executions, and another to [handle](https://gitlab.com/gitlab-org/gitlab/-/blob/44345381e89d6bbd440f7b4c680d03e8b75b86de/qa/qa/tools/test_resources_handler.rb#L44)
+these resources. On [dotcom environments](https://about.gitlab.com/handbook/engineering/infrastructure/environments/#environments), after a test suite finishes in the [QA pipelines](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/debugging-qa-test-failures/#scheduled-qa-test-pipelines), resources from all passing test are
+automatically deleted in the same pipeline run. Resources from all failed tests are reserved for investigation,
+and won't be deleted until the following Saturday by a scheduled pipeline. When introducing new resources, please
+also make sure to add any resource that cannot be deleted to the [IGNORED_RESOURCES](https://gitlab.com/gitlab-org/gitlab/-/blob/44345381e89d6bbd440f7b4c680d03e8b75b86de/qa/qa/tools/test_resources_handler.rb#L29)
+list.
+
## Where to ask for help?
If you need more information, ask for help on `#quality` channel on Slack
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index ad9ed80f0d0..56e7d1a03a0 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -397,11 +397,10 @@ To support the following package managers, the GitLab analyzers proceed in two s
If your project <i>does not use</i> a <code>gradlew</code> file, then the analyzer automatically switches to one of the
pre-installed Gradle versions, based on the version of Java specified by the
<a href="#configuring-specific-analyzers-used-by-dependency-scanning"><code>DS_JAVA_VERSION</code></a> variable.
+ By default, the analyzer uses Java 17 and Gradle 7.3.3.
</p>
- <p>You can view the
- <a href="https://docs.gradle.org/current/userguide/compatibility.html#java">Gradle Java compatibility matrix</a> to see which version
- of Gradle is selected for each Java version. Note that we only support switching to one of these pre-installed Gradle versions
- for Java versions 13 to 17.
+ <p>
+ For Java versions <code>8</code> and <code>11</code>, Gradle <code>6.7.1</code> is automatically selected, and for Java versions <code>13</code> to <code>17</code>, Gradle <code>7.3.3</code> is automatically selected.
</p>
</li>
<li>
diff --git a/lib/gitlab/ci/config/external/file/project.rb b/lib/gitlab/ci/config/external/file/project.rb
index b7fef081269..89418bd6a21 100644
--- a/lib/gitlab/ci/config/external/file/project.rb
+++ b/lib/gitlab/ci/config/external/file/project.rb
@@ -13,7 +13,7 @@ module Gitlab
def initialize(params, context)
@location = params[:file]
- @project_name = params[:project]
+ @project_name = get_project_name(params[:project])
@ref_name = params[:ref] || 'HEAD'
super
@@ -122,6 +122,16 @@ module Gitlab
)
end
end
+
+ # TODO: To be removed after we deprecate usage of array in `project` keyword.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/365975
+ def get_project_name(project_name)
+ if project_name.is_a?(Array)
+ project_name.first
+ else
+ project_name
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/runner_upgrade_check.rb b/lib/gitlab/ci/runner_upgrade_check.rb
index ad0fd73e9da..4ca99e4d175 100644
--- a/lib/gitlab/ci/runner_upgrade_check.rb
+++ b/lib/gitlab/ci/runner_upgrade_check.rb
@@ -5,13 +5,6 @@ module Gitlab
class RunnerUpgradeCheck
include Singleton
- STATUSES = {
- invalid: 'Runner version is not valid.',
- not_available: 'Upgrade is not available for the runner.',
- available: 'Upgrade is available for the runner.',
- recommended: 'Upgrade is available and recommended for the runner.'
- }.freeze
-
def check_runner_upgrade_status(runner_version)
runner_version = ::Gitlab::VersionInfo.parse(runner_version, parse_suffix: true)
diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml
index 17078dde9d8..2a3ce6152ab 100644
--- a/lib/gitlab/database/gitlab_schemas.yml
+++ b/lib/gitlab/database/gitlab_schemas.yml
@@ -108,6 +108,7 @@ ci_resource_groups: :gitlab_ci
ci_resources: :gitlab_ci
ci_runner_namespaces: :gitlab_ci
ci_runner_projects: :gitlab_ci
+ci_runner_versions: :gitlab_ci
ci_runners: :gitlab_ci
ci_running_builds: :gitlab_ci
ci_sources_pipelines: :gitlab_ci
diff --git a/lib/gitlab/usage_data_counters/known_events/analytics.yml b/lib/gitlab/usage_data_counters/known_events/analytics.yml
index 5a1e7f03278..733f570d2e8 100644
--- a/lib/gitlab/usage_data_counters/known_events/analytics.yml
+++ b/lib/gitlab/usage_data_counters/known_events/analytics.yml
@@ -78,3 +78,23 @@
category: analytics
redis_slot: analytics
aggregation: weekly
+- name: p_analytics_ci_cd_time_to_restore_service
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+- name: g_analytics_ci_cd_release_statistics
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+- name: g_analytics_ci_cd_deployment_frequency
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+- name: g_analytics_ci_cd_lead_time
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+- name: g_analytics_ci_cd_time_to_restore_service
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 855351af270..1e1307276fe 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7734,6 +7734,12 @@ msgstr ""
msgid "Checkout|Group"
msgstr ""
+msgid "Checkout|Must be %{minimumNumberOfUsers} (your seats in use) or more."
+msgstr ""
+
+msgid "Checkout|Must be %{minimumNumberOfUsers} (your seats in use, plus all over limit members) or more. To buy fewer seats, remove members from the group."
+msgstr ""
+
msgid "Checkout|Name of company or organization using GitLab"
msgstr ""
@@ -7785,9 +7791,6 @@ msgstr ""
msgid "Checkout|Tax"
msgstr ""
-msgid "Checkout|This number must be %{minimumNumberOfUsers} (your seats in use) or more."
-msgstr ""
-
msgid "Checkout|Total"
msgstr ""
diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb
index f968fb8b26c..0030a47ed55 100644
--- a/qa/qa/tools/test_resources_handler.rb
+++ b/qa/qa/tools/test_resources_handler.rb
@@ -31,7 +31,8 @@ module QA
'QA::Resource::CiVariable',
'QA::Resource::Repository::Commit',
'QA::EE::Resource::GroupIteration',
- 'QA::EE::Resource::Settings::Elasticsearch'
+ 'QA::EE::Resource::Settings::Elasticsearch',
+ 'QA::EE::Resource::VulnerabilityItem'
].freeze
PROJECT = 'gitlab-qa-resources'
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index b3b803649d1..92fa5d4f51e 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -827,6 +827,10 @@ RSpec.describe Projects::PipelinesController do
{
chart_param: 'lead-time',
event: 'p_analytics_ci_cd_lead_time'
+ },
+ {
+ chart_param: 'time-to-restore-service',
+ event: 'p_analytics_ci_cd_time_to_restore_service'
}
].each do |tab|
it_behaves_like 'tracking unique visits', :charts do
diff --git a/spec/factories/ci/runner_versions.rb b/spec/factories/ci/runner_versions.rb
new file mode 100644
index 00000000000..69127aa6e54
--- /dev/null
+++ b/spec/factories/ci/runner_versions.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_runner_version, class: 'Ci::RunnerVersion' do
+ sequence(:version) { |n| "1.0.#{n}" }
+ end
+end
diff --git a/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb b/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb
index 81a852471b9..d85808d9d61 100644
--- a/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb
+++ b/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb
@@ -5,9 +5,12 @@ require 'spec_helper'
RSpec.describe Types::Ci::RunnerUpgradeStatusTypeEnum do
specify { expect(described_class.graphql_name).to eq('CiRunnerUpgradeStatusType') }
- it 'exposes all upgrade status values' do
- expect(described_class.values.keys).to eq(
- ['UNKNOWN'] + ::Gitlab::Ci::RunnerUpgradeCheck::STATUSES.map { |sym, _| sym.to_s.upcase }
+ it 'exposes all upgrade status values except not_processed' do
+ expect(described_class.values.keys).to match_array(
+ Ci::RunnerVersion.statuses.keys
+ .reject { |k| k == 'not_processed' }
+ .map { |k| k.upcase }
+ .map { |v| v == 'INVALID_VERSION' ? 'INVALID' : v }
)
end
end
diff --git a/spec/initializers/1_acts_as_taggable_spec.rb b/spec/initializers/1_acts_as_taggable_spec.rb
new file mode 100644
index 00000000000..f9ccc9718d5
--- /dev/null
+++ b/spec/initializers/1_acts_as_taggable_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'ActsAsTaggableOn::Tag' do
+ describe '.find_or_create_all_with_like_by_name' do
+ let(:tags) { %w[tag] }
+
+ subject(:find_or_create) { ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tags) }
+
+ it 'creates a tag' do
+ expect { find_or_create }.to change(ActsAsTaggableOn::Tag, :count).by(1)
+ end
+
+ it 'returns the Tag record' do
+ results = find_or_create
+
+ expect(results.size).to eq(1)
+ expect(results.first).to be_an_instance_of(ActsAsTaggableOn::Tag)
+ expect(results.first.name).to eq('tag')
+ end
+
+ context 'some tags already existing' do
+ let(:tags) { %w[tag preexisting_tag tag2] }
+
+ before_all do
+ ActsAsTaggableOn::Tag.create!(name: 'preexisting_tag')
+ end
+
+ it 'creates only the missing tag' do
+ expect(ActsAsTaggableOn::Tag).to receive(:insert_all)
+ .with([{ name: 'tag' }, { name: 'tag2' }], unique_by: :name)
+ .and_call_original
+
+ expect { find_or_create }.to change(ActsAsTaggableOn::Tag, :count).by(2)
+ end
+
+ it 'returns the Tag records' do
+ results = find_or_create
+
+ expect(results.map(&:name)).to match_array(tags)
+ end
+ end
+
+ context 'all tags already existing' do
+ let(:tags) { %w[preexisting_tag preexisting_tag2] }
+
+ before_all do
+ ActsAsTaggableOn::Tag.create!(name: 'preexisting_tag')
+ ActsAsTaggableOn::Tag.create!(name: 'preexisting_tag2')
+ end
+
+ it 'does not create new tags' do
+ expect { find_or_create }.not_to change(ActsAsTaggableOn::Tag, :count)
+ end
+
+ it 'returns the Tag records' do
+ results = find_or_create
+
+ expect(results.map(&:name)).to match_array(tags)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/external/file/project_spec.rb b/spec/lib/gitlab/ci/config/external/file/project_spec.rb
index 77e542cf933..72a85c9b03d 100644
--- a/spec/lib/gitlab/ci/config/external/file/project_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/project_spec.rb
@@ -177,6 +177,22 @@ RSpec.describe Gitlab::Ci::Config::External::File::Project do
expect(project_file.error_message).to include("Project `xxxxxxxxxxxxxxxxxxxxxxx` not found or access denied!")
end
end
+
+ context 'when a project contained in an array is used with a masked variable' do
+ let(:variables) do
+ Gitlab::Ci::Variables::Collection.new([
+ { key: 'VAR1', value: 'a_secret_variable_value', masked: true }
+ ])
+ end
+
+ let(:params) do
+ { project: ['a_secret_variable_value'], file: '/file.yml' }
+ end
+
+ it 'does not raise an error' do
+ expect { valid? }.not_to raise_error
+ end
+ end
end
describe '#expand_context' do
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index b1f5cca647b..63f2731e4d1 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -35,6 +35,46 @@ RSpec.describe Ci::Runner do
end
end
+ describe 'acts_as_taggable' do
+ let(:tag_name) { 'tag123' }
+
+ context 'on save' do
+ let_it_be_with_reload(:runner) { create(:ci_runner) }
+
+ before do
+ runner.tag_list = [tag_name]
+ end
+
+ context 'tag does not exist' do
+ it 'creates a tag' do
+ expect { runner.save! }.to change(ActsAsTaggableOn::Tag, :count).by(1)
+ end
+
+ it 'creates an association to the tag' do
+ runner.save!
+
+ expect(described_class.tagged_with(tag_name)).to include(runner)
+ end
+ end
+
+ context 'tag already exists' do
+ before do
+ ActsAsTaggableOn::Tag.create!(name: tag_name)
+ end
+
+ it 'does not create a tag' do
+ expect { runner.save! }.not_to change(ActsAsTaggableOn::Tag, :count)
+ end
+
+ it 'creates an association to the tag' do
+ runner.save!
+
+ expect(described_class.tagged_with(tag_name)).to include(runner)
+ end
+ end
+ end
+ end
+
describe 'validation' do
it { is_expected.to validate_presence_of(:access_level) }
it { is_expected.to validate_presence_of(:runner_type) }
diff --git a/spec/models/ci/runner_version_spec.rb b/spec/models/ci/runner_version_spec.rb
new file mode 100644
index 00000000000..0303e0bb657
--- /dev/null
+++ b/spec/models/ci/runner_version_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::RunnerVersion do
+ it_behaves_like 'having unique enum values'
+
+ describe '.not_available' do
+ subject { described_class.not_available }
+
+ let!(:runner_version1) { create(:ci_runner_version, version: 'abc123', status: :not_available) }
+ let!(:runner_version2) { create(:ci_runner_version, version: 'abc234', status: :recommended) }
+
+ it { is_expected.to match_array([runner_version1]) }
+ end
+
+ describe 'validation' do
+ context 'when runner version is too long' do
+ let(:runner_version) { build(:ci_runner_version, version: 'a' * 2049) }
+
+ it 'is not valid' do
+ expect(runner_version).to be_invalid
+ end
+ end
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 48bd3bdf7eb..7a5908fb586 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1109,6 +1109,20 @@ RSpec.describe User do
.to contain_exactly(user1, user2)
end
end
+
+ describe '.order_recent_last_activity' do
+ it 'sorts users by activity and id to make the ordes deterministic' do
+ expect(described_class.order_recent_last_activity.to_sql).to include(
+ 'ORDER BY "users"."last_activity_on" DESC NULLS LAST, "users"."id" ASC')
+ end
+ end
+
+ describe '.order_oldest_last_activity' do
+ it 'sorts users by activity and id to make the ordes deterministic' do
+ expect(described_class.order_oldest_last_activity.to_sql).to include(
+ 'ORDER BY "users"."last_activity_on" ASC NULLS FIRST, "users"."id" DESC')
+ end
+ end
end
context 'strip attributes' do
@@ -3518,49 +3532,45 @@ RSpec.describe User do
end
describe '#sort_by_attribute' do
- before do
- described_class.delete_all
- @user = create :user, created_at: Date.today, current_sign_in_at: Date.today, name: 'Alpha'
- @user1 = create :user, created_at: Date.today - 1, current_sign_in_at: Date.today - 1, name: 'Omega'
- @user2 = create :user, created_at: Date.today - 2, name: 'Beta'
- end
+ let_it_be(:user) { create :user, created_at: Date.today, current_sign_in_at: Date.today, username: 'user0' }
+ let_it_be(:user1) { create :user, created_at: Date.today - 1, last_activity_on: Date.today - 1, current_sign_in_at: Date.today - 1, username: 'user1' }
+ let_it_be(:user2) { create :user, created_at: Date.today - 2, username: 'user2' }
+ let_it_be(:user3) { create :user, created_at: Date.today - 3, last_activity_on: Date.today, username: "user3" }
context 'when sort by recent_sign_in' do
let(:users) { described_class.sort_by_attribute('recent_sign_in') }
- it 'sorts users by recent sign-in time' do
- expect(users.first).to eq(@user)
- expect(users.second).to eq(@user1)
- end
-
- it 'pushes users who never signed in to the end' do
- expect(users.third).to eq(@user2)
+ it 'sorts users by recent sign-in time with user that never signed in at the end' do
+ expect(users).to eq([user, user1, user2, user3])
end
end
context 'when sort by oldest_sign_in' do
let(:users) { described_class.sort_by_attribute('oldest_sign_in') }
- it 'sorts users by the oldest sign-in time' do
- expect(users.first).to eq(@user1)
- expect(users.second).to eq(@user)
- end
-
- it 'pushes users who never signed in to the end' do
- expect(users.third).to eq(@user2)
+ it 'sorts users by the oldest sign-in time with users that never signed in at the end' do
+ expect(users).to eq([user1, user, user2, user3])
end
end
it 'sorts users in descending order by their creation time' do
- expect(described_class.sort_by_attribute('created_desc').first).to eq(@user)
+ expect(described_class.sort_by_attribute('created_desc')).to eq([user, user1, user2, user3])
end
it 'sorts users in ascending order by their creation time' do
- expect(described_class.sort_by_attribute('created_asc').first).to eq(@user2)
+ expect(described_class.sort_by_attribute('created_asc')).to eq([user3, user2, user1, user])
end
it 'sorts users by id in descending order when nil is passed' do
- expect(described_class.sort_by_attribute(nil).first).to eq(@user2)
+ expect(described_class.sort_by_attribute(nil)).to eq([user3, user2, user1, user])
+ end
+
+ it 'sorts user by latest activity descending, nulls last ordered by ascending id' do
+ expect(described_class.sort_by_attribute('last_activity_on_desc')).to eq([user3, user1, user, user2])
+ end
+
+ it 'sorts user by latest activity ascending, nulls first ordered by descending id' do
+ expect(described_class.sort_by_attribute('last_activity_on_asc')).to eq([user2, user, user1, user3])
end
end