mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-03 16:04:30 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
4
Gemfile
4
Gemfile
@ -34,9 +34,9 @@ gem 'bootsnap', '~> 1.18.3', require: false, feature_category: :shared
|
|||||||
# Avoid the precompiled native gems because Omnibus needs to build this to ensure
|
# Avoid the precompiled native gems because Omnibus needs to build this to ensure
|
||||||
# LD_LIBRARY_PATH is correct: https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/7730
|
# LD_LIBRARY_PATH is correct: https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/7730
|
||||||
if RUBY_PLATFORM.include?('darwin')
|
if RUBY_PLATFORM.include?('darwin')
|
||||||
gem 'ffi', '~> 1.17', feature_category: :shared
|
gem 'ffi', '~> 1.17.2', feature_category: :shared
|
||||||
else
|
else
|
||||||
gem 'ffi', '~> 1.17', force_ruby_platform: true, feature_category: :shared
|
gem 'ffi', '~> 1.17.2', force_ruby_platform: true, feature_category: :shared
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'openssl', '~> 3.0', feature_category: :shared
|
gem 'openssl', '~> 3.0', feature_category: :shared
|
||||||
|
@ -2139,7 +2139,7 @@ DEPENDENCIES
|
|||||||
faraday_middleware-aws-sigv4 (~> 1.0.1)
|
faraday_middleware-aws-sigv4 (~> 1.0.1)
|
||||||
fast_blank (~> 1.0.1)
|
fast_blank (~> 1.0.1)
|
||||||
ffaker (~> 2.24)
|
ffaker (~> 2.24)
|
||||||
ffi (~> 1.17)
|
ffi (~> 1.17.2)
|
||||||
flipper (~> 0.28.0)
|
flipper (~> 0.28.0)
|
||||||
flipper-active_record (~> 0.28.0)
|
flipper-active_record (~> 0.28.0)
|
||||||
flipper-active_support_cache_store (~> 0.28.0)
|
flipper-active_support_cache_store (~> 0.28.0)
|
||||||
|
@ -2139,7 +2139,7 @@ DEPENDENCIES
|
|||||||
faraday_middleware-aws-sigv4 (~> 1.0.1)
|
faraday_middleware-aws-sigv4 (~> 1.0.1)
|
||||||
fast_blank (~> 1.0.1)
|
fast_blank (~> 1.0.1)
|
||||||
ffaker (~> 2.24)
|
ffaker (~> 2.24)
|
||||||
ffi (~> 1.17)
|
ffi (~> 1.17.2)
|
||||||
flipper (~> 0.28.0)
|
flipper (~> 0.28.0)
|
||||||
flipper-active_record (~> 0.28.0)
|
flipper-active_record (~> 0.28.0)
|
||||||
flipper-active_support_cache_store (~> 0.28.0)
|
flipper-active_support_cache_store (~> 0.28.0)
|
||||||
|
@ -33,6 +33,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
hasError: false,
|
hasError: false,
|
||||||
blobSearch: {},
|
blobSearch: {},
|
||||||
|
loaded: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
@ -66,6 +67,7 @@ export default {
|
|||||||
},
|
},
|
||||||
result({ data }) {
|
result({ data }) {
|
||||||
this.hasError = false;
|
this.hasError = false;
|
||||||
|
this.loaded = true;
|
||||||
this.blobSearch = data?.blobSearch;
|
this.blobSearch = data?.blobSearch;
|
||||||
this.$store.commit(RECEIVE_NAVIGATION_COUNT, {
|
this.$store.commit(RECEIVE_NAVIGATION_COUNT, {
|
||||||
key: 'blobs',
|
key: 'blobs',
|
||||||
@ -75,6 +77,7 @@ export default {
|
|||||||
debounce: 500,
|
debounce: 500,
|
||||||
error(error) {
|
error(error) {
|
||||||
logError(error);
|
logError(error);
|
||||||
|
this.loaded = true;
|
||||||
this.hasError = true;
|
this.hasError = true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -85,6 +88,9 @@ export default {
|
|||||||
return this.query?.page ? parseInt(this.query?.page, 10) : 1;
|
return this.query?.page ? parseInt(this.query?.page, 10) : 1;
|
||||||
},
|
},
|
||||||
isLoading() {
|
isLoading() {
|
||||||
|
if (!this.loaded && !this.$apollo?.queries?.blobSearch?.loading) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return this.$apollo.queries.blobSearch.loading;
|
return this.$apollo.queries.blobSearch.loading;
|
||||||
},
|
},
|
||||||
hasResults() {
|
hasResults() {
|
||||||
@ -99,13 +105,13 @@ export default {
|
|||||||
<error-result v-if="hasError" />
|
<error-result v-if="hasError" />
|
||||||
<section v-else>
|
<section v-else>
|
||||||
<status-bar v-if="!isLoading" :blob-search="blobSearch" />
|
<status-bar v-if="!isLoading" :blob-search="blobSearch" />
|
||||||
<empty-result v-if="!hasResults && !isLoading" />
|
|
||||||
<zoekt-blob-results
|
<zoekt-blob-results
|
||||||
v-if="hasResults || isLoading"
|
v-if="hasResults || isLoading"
|
||||||
:blob-search="blobSearch"
|
:blob-search="blobSearch"
|
||||||
:has-results="hasResults"
|
:has-results="hasResults"
|
||||||
:is-loading="isLoading"
|
:is-loading="isLoading"
|
||||||
/>
|
/>
|
||||||
|
<empty-result v-else />
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AsyncRemoveIdxCiJobVariablesOnPartitionIdJobId < Gitlab::Database::Migration[2.3]
|
||||||
|
milestone '18.1'
|
||||||
|
|
||||||
|
TABLE_NAME = :ci_job_variables
|
||||||
|
INDEX_NAME = :index_ci_job_variables_on_partition_id_job_id
|
||||||
|
COLUMNS = [:partition_id, :job_id]
|
||||||
|
|
||||||
|
# TODO: Index to be destroyed synchronously in https://gitlab.com/gitlab-org/gitlab/-/issues/544929
|
||||||
|
def up
|
||||||
|
prepare_async_index_removal TABLE_NAME, COLUMNS, name: INDEX_NAME
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
unprepare_async_index TABLE_NAME, COLUMNS, name: INDEX_NAME
|
||||||
|
end
|
||||||
|
end
|
1
db/schema_migrations/20250527170705
Normal file
1
db/schema_migrations/20250527170705
Normal file
@ -0,0 +1 @@
|
|||||||
|
896e1bab1741d053b090890c71e2f5cea31d41e8532ffee8782e41bfce8c8add
|
@ -20,15 +20,15 @@ and back up GitLab.
|
|||||||
|
|
||||||
Authentication is the first step in making your installation secure.
|
Authentication is the first step in making your installation secure.
|
||||||
|
|
||||||
- [Enforce two-factor authentication (2FA) for all users](../security/two_factor_authentication.md). We highly recommended 2FA for GitLab Self-Managed instances.
|
- [Enforce two-factor authentication (2FA) for all users](../security/two_factor_authentication.md). You should use 2FA for GitLab Self-Managed instances.
|
||||||
- Ensure users do the following:
|
- Ensure users do the following:
|
||||||
- Choose a strong, secure password. If possible, store it in a password management system.
|
- Choose a strong, secure password. If possible, store it in a password management system.
|
||||||
- If it is not configured for everyone, enable [two-factor authentication (2FA)](../user/profile/account/two_factor_authentication.md) for your account.
|
- If it is not configured for everyone, turn on [two-factor authentication (2FA)](../user/profile/account/two_factor_authentication.md) for your account.
|
||||||
This one-time secret code is an additional safeguard that keeps intruders out, even if they have your password.
|
This one-time secret code is an additional safeguard that keeps intruders out, even if they have your password.
|
||||||
- Add a backup email. If you lose access to your account, the GitLab Support team can help you more quickly.
|
- Add a backup email. If you lose access to your account, the GitLab Support team can help you more quickly.
|
||||||
- Save or print your recovery codes. If you can't access your authentication device, you can use these recovery codes to sign in to your GitLab account.
|
- Save or print your recovery codes. If you can't access your authentication device, you can use these recovery codes to sign in to your GitLab account.
|
||||||
- Add [an SSH key](../user/ssh.md) to your profile. You can generate new recovery codes as needed with SSH.
|
- Add [an SSH key](../user/ssh.md) to your profile. You can generate recovery codes as needed with SSH.
|
||||||
- Enable [personal access tokens](../user/profile/personal_access_tokens.md). When using 2FA, you can use these tokens to access the GitLab API.
|
- Create [personal access tokens](../user/profile/personal_access_tokens.md). When you use 2FA, you can use these tokens to access the GitLab API.
|
||||||
|
|
||||||
## Projects and groups
|
## Projects and groups
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ Get started:
|
|||||||
- [Add members](../user/group/_index.md#add-users-to-a-group) to the group.
|
- [Add members](../user/group/_index.md#add-users-to-a-group) to the group.
|
||||||
- Create a [subgroup](../user/group/subgroups/_index.md#create-a-subgroup).
|
- Create a [subgroup](../user/group/subgroups/_index.md#create-a-subgroup).
|
||||||
- [Add members](../user/group/subgroups/_index.md#subgroup-membership) to the subgroup.
|
- [Add members](../user/group/subgroups/_index.md#subgroup-membership) to the subgroup.
|
||||||
- Enable [external authorization control](settings/external_authorization.md#configuration).
|
- Turn on [external authorization control](settings/external_authorization.md#configuration).
|
||||||
|
|
||||||
**More resources**
|
**More resources**
|
||||||
|
|
||||||
@ -60,10 +60,10 @@ Get started:
|
|||||||
|
|
||||||
## Import projects
|
## Import projects
|
||||||
|
|
||||||
You may need to import projects from external sources like GitHub, Bitbucket, or another instance of GitLab. Many external sources can be imported into GitLab.
|
You might have to import projects from external sources like GitHub, Bitbucket, or another instance of GitLab. Many external sources can be imported into GitLab.
|
||||||
|
|
||||||
- Review the [GitLab projects documentation](../user/project/_index.md).
|
- Review the [GitLab projects documentation](../user/project/_index.md).
|
||||||
- Consider [repository mirroring](../user/project/repository/mirror/_index.md), an [alternative to project migrations](../ci/ci_cd_for_external_repos/_index.md).
|
- Consider [Repository Mirroring](../user/project/repository/mirror/_index.md), an [alternative to project migrations](../ci/ci_cd_for_external_repos/_index.md).
|
||||||
- Check out our [migration index](../user/project/import/_index.md) for documentation on common migration paths.
|
- Check out our [migration index](../user/project/import/_index.md) for documentation on common migration paths.
|
||||||
- Schedule your project exports with our [import/export API](../api/project_import_export.md#schedule-an-export).
|
- Schedule your project exports with our [import/export API](../api/project_import_export.md#schedule-an-export).
|
||||||
|
|
||||||
@ -82,18 +82,18 @@ While this isn't an exhaustive list, following these steps gives you a solid sta
|
|||||||
|
|
||||||
- Use a long root password, stored in a vault.
|
- Use a long root password, stored in a vault.
|
||||||
- Install trusted SSL certificate and establish a process for renewal and revocation.
|
- Install trusted SSL certificate and establish a process for renewal and revocation.
|
||||||
- [Configure SSH key restrictions](../security/ssh_keys_restrictions.md) per your organization's guidelines.
|
- [Configure SSH key restrictions](../security/ssh_keys_restrictions.md) according to your organization's guidelines.
|
||||||
- [Disable new sign-ups](settings/sign_up_restrictions.md#disable-new-sign-ups).
|
- [Turn off new sign-ups](settings/sign_up_restrictions.md#disable-new-sign-ups).
|
||||||
- Require email confirmation.
|
- Require email confirmation.
|
||||||
- Set password length limit, configure SSO or SAML user management.
|
- Set password length limit, configure SSO or SAML user management.
|
||||||
- Limit email domains if allowing sign-up.
|
- Limit email domains if allowing sign-up.
|
||||||
- Require two-factor authentication (2FA).
|
- Require two-factor authentication (2FA).
|
||||||
- [Disable password authentication](settings/sign_in_restrictions.md#password-authentication-enabled) for Git over HTTPS.
|
- [Turn off password authentication](settings/sign_in_restrictions.md#password-authentication-enabled) for Git over HTTPS.
|
||||||
- Set up [email notification for unknown sign-ins](settings/sign_in_restrictions.md#email-notification-for-unknown-sign-ins).
|
- Set up [email notification for unknown sign-ins](settings/sign_in_restrictions.md#email-notification-for-unknown-sign-ins).
|
||||||
- Configure [user and IP rate limits](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/#user-and-ip-rate-limits).
|
- Configure [user and IP rate limits](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/#user-and-ip-rate-limits).
|
||||||
- Limit [webhooks local access](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/#webhooks).
|
- Limit [webhooks local access](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/#webhooks).
|
||||||
- Set [rate limits for protected paths](settings/protected_paths.md).
|
- Set [rate limits for protected paths](settings/protected_paths.md).
|
||||||
- Sign up for [Security Alerts](https://about.gitlab.com/company/preference-center/) from the Communication Preference Center.
|
- Subscribe to [Security Alerts](https://about.gitlab.com/company/preference-center/) from the Communication Preference Center.
|
||||||
- Keep track of security best practices on our [blog page](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/).
|
- Keep track of security best practices on our [blog page](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/).
|
||||||
|
|
||||||
## Monitor GitLab performance
|
## Monitor GitLab performance
|
||||||
@ -104,7 +104,7 @@ Unlike other monitoring solutions (for example, Zabbix or New Relic), Prometheus
|
|||||||
- [Prometheus](monitoring/prometheus/_index.md) captures
|
- [Prometheus](monitoring/prometheus/_index.md) captures
|
||||||
[these GitLab metrics](monitoring/prometheus/gitlab_metrics.md#metrics-available).
|
[these GitLab metrics](monitoring/prometheus/gitlab_metrics.md#metrics-available).
|
||||||
- Learn more about GitLab [bundled software metrics](monitoring/prometheus/_index.md#bundled-software-metrics).
|
- Learn more about GitLab [bundled software metrics](monitoring/prometheus/_index.md#bundled-software-metrics).
|
||||||
- Prometheus and its exporters are on by default. However, you need to [configure the service](monitoring/prometheus/_index.md#configuring-prometheus).
|
- Prometheus and its exporters are on by default. However, you must [configure the service](monitoring/prometheus/_index.md#configuring-prometheus).
|
||||||
- Find out why [application performance metrics](https://about.gitlab.com/blog/2020/05/07/working-with-performance-metrics/) matter.
|
- Find out why [application performance metrics](https://about.gitlab.com/blog/2020/05/07/working-with-performance-metrics/) matter.
|
||||||
- Integrate Grafana to [build visual dashboards](https://youtu.be/f4R7s0An1qE) based on performance metrics.
|
- Integrate Grafana to [build visual dashboards](https://youtu.be/f4R7s0An1qE) based on performance metrics.
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ GitLab provides backup methods to keep your data safe and recoverable. Whether y
|
|||||||
|
|
||||||
The routine differs, depending on whether you deployed with the Linux package or the Helm chart.
|
The routine differs, depending on whether you deployed with the Linux package or the Helm chart.
|
||||||
|
|
||||||
When backing up (single node) GitLab server installed using the Linux package, you can use a single Rake task.
|
To back up a single-node installation that uses the Linux package, you can use a single Rake task.
|
||||||
|
|
||||||
Learn about [backing up Linux package or Helm variations](backup_restore/_index.md).
|
Learn about [backing up Linux package or Helm variations](backup_restore/_index.md).
|
||||||
This process backs up your entire instance, but does not back up the configuration files. Ensure those are backed up separately.
|
This process backs up your entire instance, but does not back up the configuration files. Ensure those are backed up separately.
|
||||||
@ -174,18 +174,18 @@ All backups are encrypted. After 90 days, backups are deleted.
|
|||||||
|
|
||||||
You should not use [direct transfer](../user/group/import/_index.md) or
|
You should not use [direct transfer](../user/group/import/_index.md) or
|
||||||
[project export files](../user/project/settings/import_export.md) to back up your data.
|
[project export files](../user/project/settings/import_export.md) to back up your data.
|
||||||
Using project export files for backups does not always work, and not all items are exported.
|
Project export files do not always work for data backups, and not all items are exported.
|
||||||
|
|
||||||
{{< /alert >}}
|
{{< /alert >}}
|
||||||
|
|
||||||
### Alternative backup strategies
|
### Alternative backup strategies
|
||||||
|
|
||||||
In some situations the Rake task for backups may not be the most optimal solution. Here are some
|
In some situations the Rake task for backups might not be the most optimal solution. Here are some
|
||||||
[alternatives](backup_restore/_index.md) to consider if the Rake task does not work for you.
|
[alternatives](backup_restore/_index.md) to consider if the Rake task does not work for you.
|
||||||
|
|
||||||
#### Option 1: File system snapshot
|
#### Option 1: File system snapshot
|
||||||
|
|
||||||
If your GitLab server contains a lot of Git repository data, you may find the GitLab backup script to be too slow. It can be especially slow when backing up to an offsite location.
|
If your GitLab server contains a lot of Git repository data, you might find the GitLab backup script to be too slow. It can be especially slow when backing up to an offsite location.
|
||||||
|
|
||||||
Slowness typically starts at a Git repository data size of around 200 GB. In this case, you might consider using file system snapshots as part of your backup strategy.
|
Slowness typically starts at a Git repository data size of around 200 GB. In this case, you might consider using file system snapshots as part of your backup strategy.
|
||||||
For example, consider a GitLab server with the following components:
|
For example, consider a GitLab server with the following components:
|
||||||
@ -195,7 +195,7 @@ For example, consider a GitLab server with the following components:
|
|||||||
|
|
||||||
The EC2 instance meets the requirements for an application data backup by taking an EBS snapshot. The backup includes all repositories, uploads, and PostgreSQL data.
|
The EC2 instance meets the requirements for an application data backup by taking an EBS snapshot. The backup includes all repositories, uploads, and PostgreSQL data.
|
||||||
|
|
||||||
In general, if you're running GitLab on a virtualized server, you can create VM snapshots of the entire GitLab server.
|
If you're running GitLab on a virtualized server, you can create VM snapshots of the entire GitLab server.
|
||||||
It is common for a VM snapshot to require you to power down the server.
|
It is common for a VM snapshot to require you to power down the server.
|
||||||
|
|
||||||
#### Option 2: GitLab Geo
|
#### Option 2: GitLab Geo
|
||||||
|
@ -229,6 +229,9 @@ When this feature is enabled, GitLab runs a daily job to deactivate the dormant
|
|||||||
|
|
||||||
A maximum of 100,000 users can be deactivated per day.
|
A maximum of 100,000 users can be deactivated per day.
|
||||||
|
|
||||||
|
By default, users receive an email notification when their account is deactivated.
|
||||||
|
You can disable [user deactivation emails](settings/email.md#user-deactivation-emails).
|
||||||
|
|
||||||
{{< alert type="note" >}}
|
{{< alert type="note" >}}
|
||||||
|
|
||||||
GitLab generated bots are excluded from the automatic deactivation of dormant users.
|
GitLab generated bots are excluded from the automatic deactivation of dormant users.
|
||||||
|
@ -1056,6 +1056,15 @@ Considering these, you should carefully plan your PostgreSQL upgrade:
|
|||||||
sudo gitlab-ctl pg-upgrade
|
sudo gitlab-ctl pg-upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1. Ensure that the compatible versions of `pg_dump` and `pg_restore` are used
|
||||||
|
on the GitLab Rails instance to avoid version mismatch errors when performing
|
||||||
|
a backup or restore. You can do this by specifying the PostgreSQL version
|
||||||
|
in `/etc/gitlab/gitlab.rb` on the Rails instance:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
postgresql['version'] = 16
|
||||||
|
```
|
||||||
|
|
||||||
If issues are encountered upgrading the replicas,
|
If issues are encountered upgrading the replicas,
|
||||||
[there is a troubleshooting section](replication_and_failover_troubleshooting.md#postgresql-major-version-upgrade-fails-on-a-patroni-replica) that might be the solution.
|
[there is a troubleshooting section](replication_and_failover_troubleshooting.md#postgresql-major-version-upgrade-fails-on-a-patroni-replica) that might be the solution.
|
||||||
|
|
||||||
|
@ -510,9 +510,16 @@ only use this suffix for associations between two tables. If you want to
|
|||||||
reference an ID on a third party platform the `_xid` suffix is recommended.
|
reference an ID on a third party platform the `_xid` suffix is recommended.
|
||||||
|
|
||||||
The spec `spec/db/schema_spec.rb` tests if all columns with the `_id` suffix
|
The spec `spec/db/schema_spec.rb` tests if all columns with the `_id` suffix
|
||||||
have a foreign key constraint. So if that spec fails, don't add the column to
|
have a foreign key constraint. If that spec fails, add the column to
|
||||||
`IGNORED_FK_COLUMNS`, but instead add the FK constraint, or consider naming it
|
`ignored_fk_columns_map` if the column fits any of the two criteria:
|
||||||
differently.
|
|
||||||
|
1. The column references another table, such as the two tables belong to
|
||||||
|
[GitLab schemas](multiple_databases.md#gitlab-schema) that don't
|
||||||
|
allow Foreign Keys between them.
|
||||||
|
1. The foreign key is replaced by a [Loose Foreign Key](loose_foreign_keys.md) for performance reasons.
|
||||||
|
1. The column represents a [polymorphic relationship](polymorphic_associations.md). Note that polymorphic associations should not be used.
|
||||||
|
1. The column is not meant to reference another table. For example, it's common to have `partition_id`
|
||||||
|
for partitioned tables.
|
||||||
|
|
||||||
## Dependent removals
|
## Dependent removals
|
||||||
|
|
||||||
|
@ -20,6 +20,14 @@ module Gitlab
|
|||||||
execute("ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL")
|
execute("ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reset_all_trigger_functions(table_name)
|
||||||
|
triggers = find_table_triggers(table_name)
|
||||||
|
|
||||||
|
triggers.each do |trigger|
|
||||||
|
reset_trigger_function(trigger['function_name'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def function_exists?(name)
|
def function_exists?(name)
|
||||||
!!connection.select_value("SELECT 1 FROM pg_proc WHERE proname = '#{name}'")
|
!!connection.select_value("SELECT 1 FROM pg_proc WHERE proname = '#{name}'")
|
||||||
end
|
end
|
||||||
@ -136,6 +144,21 @@ module Gitlab
|
|||||||
def optional_clause(flag, clause)
|
def optional_clause(flag, clause)
|
||||||
flag ? clause : ""
|
flag ? clause : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_table_triggers(table_name)
|
||||||
|
schema_qualified_table = "#{quote_table_name(current_schema)}.#{quote_table_name(table_name)}"
|
||||||
|
|
||||||
|
triggers_query = <<~SQL
|
||||||
|
SELECT DISTINCT
|
||||||
|
p.proname AS function_name
|
||||||
|
FROM pg_trigger tr
|
||||||
|
JOIN pg_proc p ON tr.tgfoid = p.oid
|
||||||
|
WHERE tr.tgisinternal IS FALSE
|
||||||
|
AND tr.tgrelid = '#{schema_qualified_table}'::regclass
|
||||||
|
SQL
|
||||||
|
|
||||||
|
select_all(triggers_query).to_a
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -25,8 +25,9 @@ RSpec.describe 'Database schema',
|
|||||||
}.with_indifferent_access.freeze
|
}.with_indifferent_access.freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
# List of columns historically missing a FK, don't add more columns
|
# List of columns, ending with `_id` but missing a FK
|
||||||
# See: https://docs.gitlab.com/ee/development/database/foreign_keys.html#naming-foreign-keys
|
# See: https://docs.gitlab.com/ee/development/database/foreign_keys.html#naming-foreign-keys
|
||||||
|
# TODO: Automate this to reduce the list of exceptions: https://gitlab.com/gitlab-org/gitlab/-/issues/544795
|
||||||
let(:ignored_fk_columns_map) do
|
let(:ignored_fk_columns_map) do
|
||||||
{
|
{
|
||||||
abuse_reports: %w[reporter_id user_id],
|
abuse_reports: %w[reporter_id user_id],
|
||||||
|
@ -101,7 +101,7 @@ describe('GlobalSearchResultsApp', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
createComponent({
|
createComponent({
|
||||||
initialState: {
|
initialState: {
|
||||||
query: { scope: 'blobs' },
|
query: { scope: 'blobs', search: 'foo' },
|
||||||
searchType: 'zoekt',
|
searchType: 'zoekt',
|
||||||
navigation: MOCK_NAVIGATION_DATA,
|
navigation: MOCK_NAVIGATION_DATA,
|
||||||
},
|
},
|
||||||
|
@ -34,4 +34,79 @@ RSpec.describe Gitlab::Database::SchemaHelpers, feature_category: :database do
|
|||||||
expect(recorder.log).to include(/ALTER FUNCTION "existing_trigger_function" RESET ALL/)
|
expect(recorder.log).to include(/ALTER FUNCTION "existing_trigger_function" RESET ALL/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#reset_all_trigger_functions' do
|
||||||
|
let(:table_name) { '_test_table_for_triggers' }
|
||||||
|
let(:triggers) { [] }
|
||||||
|
|
||||||
|
before do
|
||||||
|
connection.execute(<<~SQL)
|
||||||
|
CREATE TABLE #{table_name} (
|
||||||
|
id serial PRIMARY KEY
|
||||||
|
);
|
||||||
|
SQL
|
||||||
|
|
||||||
|
triggers.pluck(:function).uniq.each do |function_name|
|
||||||
|
migration_context.create_trigger_function(function_name) { "RETURN NEW;" }
|
||||||
|
end
|
||||||
|
|
||||||
|
triggers.each do |trigger|
|
||||||
|
migration_context.create_trigger(table_name, trigger[:name], trigger[:function],
|
||||||
|
fires: 'BEFORE INSERT OR UPDATE')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when no triggers exist' do
|
||||||
|
let(:triggers) { [] }
|
||||||
|
|
||||||
|
it 'does not reset any trigger functions' do
|
||||||
|
expect(migration_context).not_to receive(:reset_trigger_function)
|
||||||
|
migration_context.reset_all_trigger_functions(table_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when one trigger exists' do
|
||||||
|
let(:triggers) do
|
||||||
|
[
|
||||||
|
{ name: 'test_trigger_1', function: 'test_function_1' }
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'resets the single trigger function' do
|
||||||
|
expect(migration_context).to receive(:reset_trigger_function).with('test_function_1').once.and_call_original
|
||||||
|
migration_context.reset_all_trigger_functions(table_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when multiple triggers exist' do
|
||||||
|
let(:triggers) do
|
||||||
|
[
|
||||||
|
{ name: 'test_trigger_1', function: 'test_function_1' },
|
||||||
|
{ name: 'test_trigger_2', function: 'test_function_2' }
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'resets multiple trigger functions' do
|
||||||
|
expect(migration_context).to receive(:reset_trigger_function).with('test_function_1').once.and_call_original
|
||||||
|
expect(migration_context).to receive(:reset_trigger_function).with('test_function_2').once.and_call_original
|
||||||
|
migration_context.reset_all_trigger_functions(table_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when different triggers use the same function' do
|
||||||
|
let(:shared_function) { 'shared_trigger_function' }
|
||||||
|
|
||||||
|
let(:triggers) do
|
||||||
|
[
|
||||||
|
{ name: 'test_trigger_1', function: shared_function },
|
||||||
|
{ name: 'test_trigger_2', function: shared_function }
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'resets the function only once' do
|
||||||
|
expect(migration_context).to receive(:reset_trigger_function).with(shared_function).once.and_call_original
|
||||||
|
migration_context.reset_all_trigger_functions(table_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user