mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-03 16:04:30 +00:00
118 lines
7.1 KiB
Markdown
118 lines
7.1 KiB
Markdown
---
|
|
stage: none
|
|
group: unassigned
|
|
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/development/development_processes/#development-guidelines-review.
|
|
title: Application settings development
|
|
---
|
|
|
|
This document provides a development guide for contributors to add application
|
|
settings to GitLab.
|
|
|
|
Application settings are stored in the `application_settings` table. Each setting has its own column and there should only be one row.
|
|
|
|
Duo-related applications settings are [stored in a different table](#adding-a-duo-related-setting).
|
|
|
|
## Add a new application setting
|
|
|
|
First of all, you have to decide if it is necessary to add an application setting.
|
|
Consider our [configuration principles](https://handbook.gitlab.com/handbook/product/product-principles/#configuration-principles) when adding a new setting.
|
|
|
|
We prefer saving the related application settings in a single JSONB column to avoid making the `application_settings`
|
|
table wider. Also, adding a new setting to an existing column doesn't require a database review so it saves time.
|
|
|
|
To add a new setting, you have to:
|
|
|
|
- Check if there is an existing JSONB column that you can use to store the new setting.
|
|
- If there is an existing JSON column then:
|
|
- Add a new setting to the JSONB column like [`rate_limits`](https://gitlab.com/gitlab-org/gitlab/-/blob/63b37287ae028842fcdcf56d311e6bb0c7e09e79/app/models/application_setting.rb#L603)
|
|
in the `ApplicationSetting` model.
|
|
- Update the JSON schema validator for the column like [`rate_limits` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/63b37287ae028842fcdcf56d311e6bb0c7e09e79/app/validators/json_schemas/application_setting_rate_limits.json).
|
|
- If there isn't an existing JSON column which you can use then:
|
|
- Add a new JSON column to the `application_settings` table to store, see this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140633/diffs) for reference.
|
|
- Add a constraint to ensure the column always stores a hash, see this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141765/diffs) for reference.
|
|
- Create follow-up issues to move existing related columns to this newly created JSONB column. Follow the process to [migrate a database columns to a JSONB column](#migrate-a-database-column-to-a-jsonb-column).
|
|
- Add the new setting to the [list of visible attributes](https://gitlab.com/gitlab-org/gitlab/-/blob/6f33ad46ffeac454c6c9ce92d6ba328a72f062fd/app/helpers/application_settings_helper.rb#L215).
|
|
- Add the new setting to the [`ApplicationSettingImplementation#defaults`](https://gitlab.com/gitlab-org/gitlab/-/blob/6f33ad46ffeac454c6c9ce92d6ba328a72f062fd/app/models/application_setting_implementation.rb#L36), if the setting has a default value.
|
|
- Add a [test for the default value](https://gitlab.com/gitlab-org/gitlab/-/blob/6f33ad46ffeac454c6c9ce92d6ba328a72f062fd/spec/models/application_setting_spec.rb#L20), if the setting has a default value.
|
|
- Add a validation for the new field to the [`ApplicationSetting` model](https://gitlab.com/gitlab-org/gitlab/-/blob/6f33ad46ffeac454c6c9ce92d6ba328a72f062fd/app/models/application_setting.rb).
|
|
- Add a [model test](https://gitlab.com/gitlab-org/gitlab/-/blob/6f33ad46ffeac454c6c9ce92d6ba328a72f062fd/spec/models/application_setting_spec.rb) for the validation and default value
|
|
- Find the [right view file](https://gitlab.com/gitlab-org/gitlab/-/tree/26ad8f4086c03283814bda50ff6e7043902cdbff/app/views/admin/application_settings) or create a new one and add a form field to the new setting.
|
|
- Update the [API documentation](https://gitlab.com/gitlab-org/gitlab/-/blob/6f33ad46ffeac454c6c9ce92d6ba328a72f062fd/doc/api/settings.md). Application settings are automatically made available on the REST API.
|
|
- Run the `scripts/cells/application-settings-analysis.rb` script to generate a definition YAML file at `config/application_setting_columns/*.yml` and update the documentation file at
|
|
[`cells/application_settings_analysis`](cells/application_settings_analysis.md), based on `db/structure.sql` and the API documentation. After the definition file is created, ensure you set the
|
|
`clusterwide` key to `true` or `false` in it. Setting `clusterwide: true` means that the attribute values are copied from the leader cell to other cells
|
|
[in the context of Cells architecture](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/cells/impacted_features/admin-area/). In most cases, `clusterwide: false` is preferable.
|
|
|
|
### Database migration example
|
|
|
|
```ruby
|
|
class AddNewSetting < Gitlab::Database::Migration[2.1]
|
|
disable_ddl_transaction!
|
|
|
|
def up
|
|
with_lock_retries do
|
|
add_column :application_settings, :new_setting, :text, if_not_exists: true
|
|
end
|
|
|
|
add_text_limit :application_settings, :new_setting, 255
|
|
end
|
|
|
|
def down
|
|
with_lock_retries do
|
|
remove_column :application_settings, :new_setting, if_exists: true
|
|
end
|
|
end
|
|
end
|
|
```
|
|
|
|
### Model validation example
|
|
|
|
```ruby
|
|
validates :new_setting,
|
|
length: { maximum: 255, message: N_('is too long (maximum is %{count} characters)') },
|
|
allow_blank: true
|
|
```
|
|
|
|
## Migrate a database column to a JSONB column
|
|
|
|
To migrate a column to JSONB, add the new setting under the JSONB accessor.
|
|
|
|
### Adding the JSONB setting
|
|
|
|
- Follow the [process to add a new application setting](#add-a-new-application-setting).
|
|
- Use the same name as the existing column to maintain consistency.
|
|
- During transition, Rails writes the same information to both the existing database
|
|
column and the field under the new JSONB column. This ensures data consistency and
|
|
prevents downtime.
|
|
|
|
### Required cleanup steps
|
|
|
|
You must follow the [process for dropping columns](database/avoiding_downtime_in_migrations.md#dropping-columns)
|
|
to remove the original column. This a required multi-milestone process that involves:
|
|
|
|
1. Ignoring the column.
|
|
1. Dropping the column.
|
|
1. Removing the ignore rule.
|
|
|
|
{{< alert type="warning" >}}
|
|
|
|
Dropping the original column before ignoring it in the model can cause problems with zero-downtime migrations.
|
|
|
|
{{< /alert >}}
|
|
|
|
### Default values
|
|
|
|
When migrating settings to JSONB columns with `jsonb_accessor` defaults,
|
|
remove them from `ApplicationSettingImplementation.defaults` because
|
|
JSONB accessors take precedence over the `defaults` method.
|
|
|
|
### Adding a Duo-related setting
|
|
|
|
We have several instance-wide GitLab Duo settings in the `application_settings` table. These include `duo_features_enabled` (boolean), `duo_workflow` (jsonb), and `duo_chat` (jsonb).
|
|
|
|
At some point, we realized it was simpler to add new instance-wide settings to a different table. Going forward, any new Duo-related instance-wide settings should be added to the `ai_settings` table.
|
|
|
|
For Duo settings at the group or project level, there is also a `namespace_ai_settings` table.
|
|
|
|
The [cascading settings framework](cascading_settings.md) assumes that the instance-wide setting is on the `application_settings` table and that group and project settings are on `namespace_settings` and `project_settings`, respectively. If you are considering adding a cascading setting for Duo, that may be a good reason to use `application_settings` instead of `ai_settings`.
|