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>2021-09-01 21:08:49 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-01 21:08:49 +0300
commitd551c55bb0e691f06655bcda5fe9566164fd3e46 (patch)
tree66320e68b9c2d3567bfbde9ad171e9543186a462 /doc/development
parent9c191c0b942eb08360f4d64c038c435b1156e15f (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc/development')
-rw-r--r--doc/development/application_limits.md4
-rw-r--r--doc/development/avoiding_downtime_in_migrations.md24
-rw-r--r--doc/development/background_migrations.md8
-rw-r--r--doc/development/cascading_settings.md2
-rw-r--r--doc/development/database/add_foreign_key_to_existing_column.md12
-rw-r--r--doc/development/database/not_null_constraints.md16
-rw-r--r--doc/development/database/rename_database_tables.md4
-rw-r--r--doc/development/database/strings_and_the_text_data_type.md21
-rw-r--r--doc/development/database/table_partitioning.md6
-rw-r--r--doc/development/i18n/externalization.md39
-rw-r--r--doc/development/migration_style_guide.md67
-rw-r--r--doc/development/prometheus_metrics.md4
-rw-r--r--doc/development/sidekiq_style_guide.md4
-rw-r--r--doc/development/single_table_inheritance.md4
-rw-r--r--doc/development/sql.md4
-rw-r--r--doc/development/testing_guide/best_practices.md76
16 files changed, 158 insertions, 137 deletions
diff --git a/doc/development/application_limits.md b/doc/development/application_limits.md
index b606cda1124..2075e7cda3c 100644
--- a/doc/development/application_limits.md
+++ b/doc/development/application_limits.md
@@ -40,9 +40,7 @@ It's recommended to create two separate migration script files.
desired limit using `create_or_update_plan_limit` migration helper, such as:
```ruby
- class InsertProjectHooksPlanLimits < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+ class InsertProjectHooksPlanLimits < Gitlab::Database::Migration[1.0]
def up
create_or_update_plan_limit('project_hooks', 'default', 0)
create_or_update_plan_limit('project_hooks', 'free', 10)
diff --git a/doc/development/avoiding_downtime_in_migrations.md b/doc/development/avoiding_downtime_in_migrations.md
index b844415c94e..9418eafa487 100644
--- a/doc/development/avoiding_downtime_in_migrations.md
+++ b/doc/development/avoiding_downtime_in_migrations.md
@@ -95,9 +95,7 @@ renaming. For example
```ruby
# A regular migration in db/migrate
-class RenameUsersUpdatedAtToUpdatedAtTimestamp < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class RenameUsersUpdatedAtToUpdatedAtTimestamp < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -125,9 +123,7 @@ We can perform this cleanup using
```ruby
# A post-deployment migration in db/post_migrate
-class CleanupUsersUpdatedAtRename < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class CleanupUsersUpdatedAtRename < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -174,9 +170,7 @@ as follows:
```ruby
# A regular migration in db/migrate
-class ChangeUsersUsernameStringToText < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ChangeUsersUsernameStringToText < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -195,9 +189,7 @@ Next we need to clean up our changes using a post-deployment migration:
```ruby
# A post-deployment migration in db/post_migrate
-class ChangeUsersUsernameStringToTextCleanup < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ChangeUsersUsernameStringToTextCleanup < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -245,9 +237,7 @@ the work / load over a longer time period, without slowing down deployments.
For example, to change the column type using a background migration:
```ruby
-class ExampleMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ExampleMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class Issue < ActiveRecord::Base
@@ -289,9 +279,7 @@ release) by a cleanup migration, which should steal from the queue and handle
any remaining rows. For example:
```ruby
-class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class MigrateRemainingIssuesClosedAt < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class Issue < ActiveRecord::Base
diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md
index 695c565ca83..123583dc9db 100644
--- a/doc/development/background_migrations.md
+++ b/doc/development/background_migrations.md
@@ -254,7 +254,7 @@ existing data. Since we're dealing with a lot of rows we'll schedule jobs in
batches instead of doing this one by one:
```ruby
-class ScheduleExtractServicesUrl < ActiveRecord::Migration[4.2]
+class ScheduleExtractServicesUrl < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -281,7 +281,7 @@ jobs and manually run on any un-migrated rows. Such a migration would look like
this:
```ruby
-class ConsumeRemainingExtractServicesUrlJobs < ActiveRecord::Migration[4.2]
+class ConsumeRemainingExtractServicesUrlJobs < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -463,8 +463,6 @@ end
```ruby
# Post deployment migration
-include Gitlab::Database::MigrationHelpers
-
MIGRATION = 'YourBackgroundMigrationName'
DELAY_INTERVAL = 2.minutes.to_i # can be different
BATCH_SIZE = 10_000 # can be different
@@ -494,8 +492,6 @@ You can reschedule pending migrations from the `background_migration_jobs` table
```ruby
# Post deployment migration
-include Gitlab::Database::MigrationHelpers
-
MIGRATION = 'YourBackgroundMigrationName'
DELAY_INTERVAL = 2.minutes
diff --git a/doc/development/cascading_settings.md b/doc/development/cascading_settings.md
index d1c5756fa2c..f5562206654 100644
--- a/doc/development/cascading_settings.md
+++ b/doc/development/cascading_settings.md
@@ -38,7 +38,7 @@ Settings are not cascading by default. To define a cascading setting, take the f
`application_settings`.
```ruby
- class AddDelayedProjectRemovalCascadingSetting < ActiveRecord::Migration[6.0]
+ class AddDelayedProjectRemovalCascadingSetting < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers::CascadingNamespaceSettings
def up
diff --git a/doc/development/database/add_foreign_key_to_existing_column.md b/doc/development/database/add_foreign_key_to_existing_column.md
index f83dc35b4a6..0e1dd0f390e 100644
--- a/doc/development/database/add_foreign_key_to_existing_column.md
+++ b/doc/development/database/add_foreign_key_to_existing_column.md
@@ -66,9 +66,7 @@ In the example above, you'd be still able to update records in the `emails` tabl
Migration file for adding `NOT VALID` foreign key:
```ruby
-class AddNotValidForeignKeyToEmailsUser < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+class AddNotValidForeignKeyToEmailsUser < Gitlab::Database::Migration[1.0]
def up
# safe to use: it requires short lock on the table since we don't validate the foreign key
add_foreign_key :emails, :users, on_delete: :cascade, validate: false
@@ -92,9 +90,7 @@ In case the data volume is higher (>1000 records), it's better to create a backg
Example for cleaning up records in the `emails` table within a database migration:
```ruby
-class RemoveRecordsWithoutUserFromEmailsTable < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+class RemoveRecordsWithoutUserFromEmailsTable < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class Email < ActiveRecord::Base
@@ -126,9 +122,7 @@ Migration file for validating the foreign key:
```ruby
# frozen_string_literal: true
-class ValidateForeignKeyOnEmailUsers < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
+class ValidateForeignKeyOnEmailUsers < Gitlab::Database::Migration[1.0]
def up
validate_foreign_key :emails, :user_id
end
diff --git a/doc/development/database/not_null_constraints.md b/doc/development/database/not_null_constraints.md
index 178a207dab5..de070f7e434 100644
--- a/doc/development/database/not_null_constraints.md
+++ b/doc/development/database/not_null_constraints.md
@@ -25,7 +25,7 @@ For example, consider a migration that creates a table with two `NOT NULL` colum
`db/migrate/20200401000001_create_db_guides.rb`:
```ruby
-class CreateDbGuides < ActiveRecord::Migration[6.0]
+class CreateDbGuides < Gitlab::Database::Migration[1.0]
def change
create_table :db_guides do |t|
t.bigint :stars, default: 0, null: false
@@ -44,7 +44,7 @@ For example, consider a migration that adds a new `NOT NULL` column `active` to
`db/migrate/20200501000001_add_active_to_db_guides.rb`:
```ruby
-class AddExtendedTitleToSprints < ActiveRecord::Migration[6.0]
+class AddExtendedTitleToSprints < Gitlab::Database::Migration[1.0]
def change
add_column :db_guides, :active, :boolean, default: true, null: false
end
@@ -111,9 +111,7 @@ with `validate: false` in a post-deployment migration,
`db/post_migrate/20200501000001_add_not_null_constraint_to_epics_description.rb`:
```ruby
-class AddNotNullConstraintToEpicsDescription < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class AddNotNullConstraintToEpicsDescription < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -144,9 +142,7 @@ so we are going to add a post-deployment migration for the 13.0 milestone (curre
`db/post_migrate/20200501000002_cleanup_epics_with_null_description.rb`:
```ruby
-class CleanupEpicsWithNullDescription < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class CleanupEpicsWithNullDescription < Gitlab::Database::Migration[1.0]
# With BATCH_SIZE=1000 and epics.count=29500 on GitLab.com
# - 30 iterations will be run
# - each requires on average ~150ms
@@ -184,9 +180,7 @@ migration helper in a final post-deployment migration,
`db/post_migrate/20200601000001_validate_not_null_constraint_on_epics_description.rb`:
```ruby
-class ValidateNotNullConstraintOnEpicsDescription < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class ValidateNotNullConstraintOnEpicsDescription < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/database/rename_database_tables.md b/doc/development/database/rename_database_tables.md
index 8ac50d2c0a0..29c17e1a235 100644
--- a/doc/development/database/rename_database_tables.md
+++ b/doc/development/database/rename_database_tables.md
@@ -60,8 +60,6 @@ Consider the next release as "Release N.M".
Execute a standard migration (not a post-migration):
```ruby
- include Gitlab::Database::MigrationHelpers
-
def up
rename_table_safely(:issues, :tickets)
end
@@ -96,8 +94,6 @@ At this point, we don't have applications using the old database table name in t
1. Remove the database view through a post-migration:
```ruby
- include Gitlab::Database::MigrationHelpers
-
def up
finalize_table_rename(:issues, :tickets)
end
diff --git a/doc/development/database/strings_and_the_text_data_type.md b/doc/development/database/strings_and_the_text_data_type.md
index 688d811b897..92d70c9cba5 100644
--- a/doc/development/database/strings_and_the_text_data_type.md
+++ b/doc/development/database/strings_and_the_text_data_type.md
@@ -47,9 +47,7 @@ For example, consider a migration that creates a table with two text columns,
`db/migrate/20200401000001_create_db_guides.rb`:
```ruby
-class CreateDbGuides < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class CreateDbGuides < Gitlab::Database::Migration[1.0]
def up
create_table_with_constraints :db_guides do |t|
t.bigint :stars, default: 0, null: false
@@ -84,7 +82,7 @@ For example, consider a migration that adds a new text column `extended_title` t
`db/migrate/20200501000001_add_extended_title_to_sprints.rb`:
```ruby
-class AddExtendedTitleToSprints < ActiveRecord::Migration[6.0]
+class AddExtendedTitleToSprints < Gitlab::Database::Migration[1.0]
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20200501000002_add_text_limit_to_sprints_extended_title
@@ -99,8 +97,7 @@ A second migration should follow the first one with a limit added to `extended_t
`db/migrate/20200501000002_add_text_limit_to_sprints_extended_title.rb`:
```ruby
-class AddTextLimitToSprintsExtendedTitle < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
+class AddTextLimitToSprintsExtendedTitle < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -175,9 +172,7 @@ in a post-deployment migration,
`db/post_migrate/20200501000001_add_text_limit_migration.rb`:
```ruby
-class AddTextLimitMigration < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class AddTextLimitMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
@@ -208,9 +203,7 @@ to add a background migration for the 13.0 milestone (current),
`db/post_migrate/20200501000002_schedule_cap_title_length_on_issues.rb`:
```ruby
-class ScheduleCapTitleLengthOnIssues < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class ScheduleCapTitleLengthOnIssues < Gitlab::Database::Migration[1.0]
# Info on how many records will be affected on GitLab.com
# time each batch needs to run on average, etc ...
BATCH_SIZE = 5000
@@ -255,9 +248,7 @@ helper in a final post-deployment migration,
`db/post_migrate/20200601000001_validate_text_limit_migration.rb`:
```ruby
-class ValidateTextLimitMigration < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
-
+class ValidateTextLimitMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/database/table_partitioning.md b/doc/development/database/table_partitioning.md
index 207d5a733ce..5319c73aad0 100644
--- a/doc/development/database/table_partitioning.md
+++ b/doc/development/database/table_partitioning.md
@@ -173,7 +173,7 @@ An example migration of partitioning the `audit_events` table by its
`created_at` column would look like:
```ruby
-class PartitionAuditEvents < ActiveRecord::Migration[6.0]
+class PartitionAuditEvents < Gitlab::Database::Migration[1.0]
include Gitlab::Database::PartitioningMigrationHelpers
def up
@@ -200,7 +200,7 @@ into the partitioned copy.
Continuing the above example, the migration would look like:
```ruby
-class BackfillPartitionAuditEvents < ActiveRecord::Migration[6.0]
+class BackfillPartitionAuditEvents < Gitlab::Database::Migration[1.0]
include Gitlab::Database::PartitioningMigrationHelpers
def up
@@ -233,7 +233,7 @@ failed jobs.
Once again, continuing the example, this migration would look like:
```ruby
-class CleanupPartitionedAuditEventsBackfill < ActiveRecord::Migration[6.0]
+class CleanupPartitionedAuditEventsBackfill < Gitlab::Database::Migration[1.0]
include Gitlab::Database::PartitioningMigrationHelpers
def up
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index 53825f0904a..517a59a0ff3 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -171,6 +171,45 @@ If you need to translate strings in the Vue component's JavaScript, you can impo
To test Vue translations, learn about [manually testing translations from the UI](#manually-test-translations-from-the-ui).
+### Test files
+
+Test expectations against externalized contents should not be hard coded,
+because we may need to run the tests with non-default locale, and tests with
+hard coded contents will fail.
+
+This means any expectations against externalized contents should call the
+same externalizing method to match the translation.
+
+Bad:
+
+```ruby
+click_button 'Submit review'
+
+expect(rendered).to have_content('Thank you for your feedback!')
+```
+
+Good:
+
+```ruby
+click_button _('Submit review')
+
+expect(rendered).to have_content(_('Thank you for your feedback!'))
+```
+
+This includes JavaScript tests:
+
+Bad:
+
+```javascript
+expect(findUpdateIgnoreStatusButton().text()).toBe('Ignore');
+```
+
+Good:
+
+```javascript
+expect(findUpdateIgnoreStatusButton().text()).toBe(__('Ignore'));
+```
+
#### Recommendations
If strings are reused throughout a component, it can be useful to define these strings as variables. We recommend defining an `i18n` property on the component's `$options` object. If there is a mixture of many-use and single-use strings in the component, consider using this approach to create a local [Single Source of Truth](https://about.gitlab.com/handbook/values/#single-source-of-truth) for externalized strings.
diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index bbaa6527e84..f6f7cfcdd6c 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -70,7 +70,7 @@ graph LR
H -->|Yes| E[Regular migration]
H -->|No| I[Post-deploy migration<br/>+ feature flag]
-
+
D -->|Yes| F[Post-deploy migration]
D -->|No| G[Background migration]
```
@@ -217,6 +217,39 @@ In case you need to insert, update, or delete a significant amount of data, you:
- Must disable the single transaction with `disable_ddl_transaction!`.
- Should consider doing it in a [Background Migration](background_migrations.md).
+## Migration helpers and versioning
+
+Various helper methods are available for many common patterns in database migrations. Those
+helpers can be found in `Gitlab::Database::MigrationHelpers` and related modules.
+
+In order to allow changing a helper's behavior over time, we implement a versioning scheme
+for migration helpers. This allows us to maintain the behavior of a helper for already
+existing migrations but change the behavior for any new migrations.
+
+For that purpose, all database migrations should inherit from `Gitlab::Database::Migration`,
+which is a "versioned" class. For new migrations, the latest version should be used (which
+can be looked up in `Gitlab::Database::Migration::MIGRATION_CLASSES`) to use the latest version
+of migration helpers.
+
+In this example, we use version 1.0 of the migration class:
+
+```ruby
+class TestMigration < Gitlab::Database::Migration[1.0]
+ def change
+ end
+end
+```
+
+NOTE:
+It is discouraged to include `Gitlab::Database::MigrationHelpers` directly into a
+migration. Instead, the latest version of `Gitlab::Database::Migration` will expose the latest
+version of migration helpers automatically.
+
+NOTE:
+Migration helpers and versioning are available starting from [14.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68986).
+For merge requests targeting previous stable branches, the old format needs to be used and we continue
+to inherit from `ActiveRecord::Migration[6.1]` instead of `Gitlab::Database::Migration[1.0]` for those.
+
## Retry mechanism when acquiring database locks
When changing the database schema, we use helper methods to invoke DDL (Data Definition
@@ -256,8 +289,6 @@ lock allow the database to process other statements.
**Removing a column:**
```ruby
-include Gitlab::Database::MigrationHelpers
-
def up
with_lock_retries do
remove_column :users, :full_name
@@ -278,8 +309,6 @@ you should do as much as possible inside the transaction rather than trying to g
Be careful about running long database statements within the block. The acquired locks are kept until the transaction (block) finishes and depending on the lock type, it might block other database operations.
```ruby
-include Gitlab::Database::MigrationHelpers
-
def up
with_lock_retries do
add_column :users, :full_name, :string
@@ -298,8 +327,6 @@ end
**Removing a foreign key:**
```ruby
-include Gitlab::Database::MigrationHelpers
-
def up
with_lock_retries do
remove_foreign_key :issues, :projects
@@ -316,8 +343,6 @@ end
**Changing default value for a column:**
```ruby
-include Gitlab::Database::MigrationHelpers
-
def up
with_lock_retries do
change_column_default :merge_requests, :lock_version, from: nil, to: 0
@@ -387,8 +412,6 @@ We can use the `add_concurrent_foreign_key` method in this case, as this helper
has the lock retries built into it.
```ruby
-include Gitlab::Database::MigrationHelpers
-
disable_ddl_transaction!
def up
@@ -405,8 +428,6 @@ end
Adding foreign key to `users`:
```ruby
-include Gitlab::Database::MigrationHelpers
-
disable_ddl_transaction!
def up
@@ -498,11 +519,11 @@ by calling the method `disable_ddl_transaction!` in the body of your migration
class like so:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
- include Gitlab::Database::MigrationHelpers
+class MyMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
INDEX_NAME = 'index_name'
+
def up
remove_concurrent_index :table_name, :column_name, name: INDEX_NAME
end
@@ -549,7 +570,7 @@ by calling the method `disable_ddl_transaction!` in the body of your migration
class like so:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
+class MyMigration < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
@@ -594,7 +615,7 @@ The easiest way to test for existence of an index by name is to use the
be used with a name option. For example:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
+class MyMigration < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers
INDEX_NAME = 'index_name'
@@ -631,7 +652,7 @@ Here's an example where we add a new column with a foreign key
constraint. Note it includes `index: true` to create an index for it.
```ruby
-class Migration < ActiveRecord::Migration[6.0]
+class Migration < Gitlab::Database::Migration[1.0]
def change
add_reference :model, :other_model, index: true, foreign_key: { on_delete: :cascade }
@@ -677,7 +698,7 @@ expensive and disruptive operation for larger tables, but in reality it's not.
Take the following migration as an example:
```ruby
-class DefaultRequestAccessGroups < ActiveRecord::Migration[5.2]
+class DefaultRequestAccessGroups < Gitlab::Database::Migration[1.0]
def change
change_column_default(:namespaces, :request_access_enabled, from: false, to: true)
end
@@ -884,7 +905,7 @@ The Rails 5 natively supports `JSONB` (binary JSON) column type.
Example migration adding this column:
```ruby
-class AddOptionsToBuildMetadata < ActiveRecord::Migration[5.0]
+class AddOptionsToBuildMetadata < Gitlab::Database::Migration[1.0]
def change
add_column :ci_builds_metadata, :config_options, :jsonb
end
@@ -916,7 +937,7 @@ Do not store `attr_encrypted` attributes as `:text` in the database; use
efficient:
```ruby
-class AddSecretToSomething < ActiveRecord::Migration[5.0]
+class AddSecretToSomething < Gitlab::Database::Migration[1.0]
def change
add_column :something, :encrypted_secret, :binary
add_column :something, :encrypted_secret_iv, :binary
@@ -974,7 +995,7 @@ If you need more complex logic, you can define and use models local to a
migration. For example:
```ruby
-class MyMigration < ActiveRecord::Migration[6.0]
+class MyMigration < Gitlab::Database::Migration[1.0]
class Project < ActiveRecord::Base
self.table_name = 'projects'
end
@@ -1073,7 +1094,7 @@ in a previous migration.
It is important not to leave out the `User.reset_column_information` command, in order to ensure that the old schema is dropped from the cache and ActiveRecord loads the updated schema information.
```ruby
-class AddAndSeedMyColumn < ActiveRecord::Migration[6.0]
+class AddAndSeedMyColumn < Gitlab::Database::Migration[1.0]
class User < ActiveRecord::Base
self.table_name = 'users'
end
diff --git a/doc/development/prometheus_metrics.md b/doc/development/prometheus_metrics.md
index 66e980978bf..da6ba14cdd8 100644
--- a/doc/development/prometheus_metrics.md
+++ b/doc/development/prometheus_metrics.md
@@ -36,9 +36,7 @@ After you add or change an existing common metric, you must [re-run the import s
Or, you can create a database migration:
```ruby
-class ImportCommonMetrics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
+class ImportCommonMetrics < Gitlab::Database::Migration[1.0]
def up
::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
end
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index 8373616ba3f..04b7e2f5c45 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -1002,9 +1002,7 @@ When renaming queues, use the `sidekiq_queue_migrate` helper migration method
in a **post-deployment migration**:
```ruby
-class MigrateTheRenamedSidekiqQueue < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
+class MigrateTheRenamedSidekiqQueue < Gitlab::Database::Migration[1.0]
def up
sidekiq_queue_migrate 'old_queue_name', to: 'new_queue_name'
end
diff --git a/doc/development/single_table_inheritance.md b/doc/development/single_table_inheritance.md
index aa4fe540b0d..eb406b02a91 100644
--- a/doc/development/single_table_inheritance.md
+++ b/doc/development/single_table_inheritance.md
@@ -31,7 +31,7 @@ could result in loading unexpected code or associations which may cause unintend
side effects or failures during upgrades.
```ruby
-class SomeMigration < ActiveRecord::Migration[6.0]
+class SomeMigration < Gitlab::Database::Migration[1.0]
class Services < ActiveRecord::Base
self.table_name = 'services'
self.inheritance_column = :_type_disabled
@@ -47,7 +47,7 @@ This ensures that the migration loads the columns for the migration in isolation
and the helper disables STI by default.
```ruby
-class EnqueueSomeBackgroundMigration < ActiveRecord::Migration[6.0]
+class EnqueueSomeBackgroundMigration < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/sql.md b/doc/development/sql.md
index 40ee19c0b9e..3483305c113 100644
--- a/doc/development/sql.md
+++ b/doc/development/sql.md
@@ -102,7 +102,7 @@ transaction. Transactions for migrations can be disabled using the following
pattern:
```ruby
-class MigrationName < ActiveRecord::Migration[4.2]
+class MigrationName < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
end
```
@@ -110,7 +110,7 @@ end
For example:
```ruby
-class AddUsersLowerUsernameEmailIndexes < ActiveRecord::Migration[4.2]
+class AddUsersLowerUsernameEmailIndexes < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index abb55857e1f..937a630f406 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -367,26 +367,34 @@ If needed, you can scope interactions within a specific area of the page by usin
As you will likely be scoping to an element such as a `div`, which typically does not have a label,
you may use a `data-testid` selector in this case.
+##### Externalized contents
+
+Test expectations against externalized contents should call the same
+externalizing method to match the translation. For example, you should use the `_`
+method in Ruby and `__` method in JavaScript.
+
+See [Internationalization for GitLab - Test files](../i18n/externalization.md#test-files) for details.
+
##### Actions
Where possible, use more specific [actions](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions), such as the ones below.
```ruby
# good
-click_button 'Submit review'
+click_button _('Submit review')
-click_link 'UI testing docs'
+click_link _('UI testing docs')
-fill_in 'Search projects', with: 'gitlab' # fill in text input with text
+fill_in _('Search projects'), with: 'gitlab' # fill in text input with text
-select 'Last updated', from: 'Sort by' # select an option from a select input
+select _('Last updated'), from: 'Sort by' # select an option from a select input
-check 'Checkbox label'
-uncheck 'Checkbox label'
+check _('Checkbox label')
+uncheck _('Checkbox label')
-choose 'Radio input label'
+choose _('Radio input label')
-attach_file('Attach a file', '/path/to/file.png')
+attach_file(_('Attach a file'), '/path/to/file.png')
# bad - interactive elements must have accessible names, so
# we should be able to use one of the specific actions above
@@ -403,17 +411,17 @@ Where possible, use more specific [finders](https://rubydoc.info/github/teamcapy
```ruby
# good
-find_button 'Submit review'
-find_button 'Submit review', disabled: true
+find_button _('Submit review')
+find_button _('Submit review'), disabled: true
-find_link 'UI testing docs'
-find_link 'UI testing docs', href: docs_url
+find_link _('UI testing docs')
+find_link _('UI testing docs'), href: docs_url
-find_field 'Search projects'
-find_field 'Search projects', with: 'gitlab' # find the input field with text
-find_field 'Search projects', disabled: true
-find_field 'Checkbox label', checked: true
-find_field 'Checkbox label', unchecked: true
+find_field _('Search projects')
+find_field _('Search projects'), with: 'gitlab' # find the input field with text
+find_field _('Search projects'), disabled: true
+find_field _('Checkbox label'), checked: true
+find_field _('Checkbox label'), unchecked: true
# acceptable when finding a element that is not a button, link, or field
find('[data-testid="element"]')
@@ -425,31 +433,31 @@ Where possible, use more specific [matchers](https://rubydoc.info/github/teamcap
```ruby
# good
-expect(page).to have_button 'Submit review'
-expect(page).to have_button 'Submit review', disabled: true
-expect(page).to have_button 'Notifications', class: 'is-checked' # assert the "Notifications" GlToggle is checked
+expect(page).to have_button _('Submit review')
+expect(page).to have_button _('Submit review'), disabled: true
+expect(page).to have_button _('Notifications'), class: 'is-checked' # assert the "Notifications" GlToggle is checked
-expect(page).to have_link 'UI testing docs'
-expect(page).to have_link 'UI testing docs', href: docs_url # assert the link has an href
+expect(page).to have_link _('UI testing docs')
+expect(page).to have_link _('UI testing docs'), href: docs_url # assert the link has an href
-expect(page).to have_field 'Search projects'
-expect(page).to have_field 'Search projects', disabled: true
-expect(page).to have_field 'Search projects', with: 'gitlab' # assert the input field has text
+expect(page).to have_field _('Search projects')
+expect(page).to have_field _('Search projects'), disabled: true
+expect(page).to have_field _('Search projects'), with: 'gitlab' # assert the input field has text
-expect(page).to have_checked_field 'Checkbox label'
-expect(page).to have_unchecked_field 'Radio input label'
+expect(page).to have_checked_field _('Checkbox label')
+expect(page).to have_unchecked_field _('Radio input label')
-expect(page).to have_select 'Sort by'
-expect(page).to have_select 'Sort by', selected: 'Last updated' # assert the option is selected
-expect(page).to have_select 'Sort by', options: ['Last updated', 'Created date', 'Due date'] # assert an exact list of options
-expect(page).to have_select 'Sort by', with_options: ['Created date', 'Due date'] # assert a partial list of options
+expect(page).to have_select _('Sort by')
+expect(page).to have_select _('Sort by'), selected: 'Last updated' # assert the option is selected
+expect(page).to have_select _('Sort by'), options: ['Last updated', 'Created date', 'Due date'] # assert an exact list of options
+expect(page).to have_select _('Sort by'), with_options: ['Created date', 'Due date'] # assert a partial list of options
-expect(page).to have_text 'Some paragraph text.'
-expect(page).to have_text 'Some paragraph text.', exact: true # assert exact match
+expect(page).to have_text _('Some paragraph text.')
+expect(page).to have_text _('Some paragraph text.'), exact: true # assert exact match
expect(page).to have_current_path 'gitlab/gitlab-test/-/issues'
-expect(page).to have_title 'Not Found'
+expect(page).to have_title _('Not Found')
# acceptable when a more specific matcher above is not possible
expect(page).to have_css 'h2', text: 'Issue title'