Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot
2023-10-05 18:09:33 +00:00
parent 3e6c042eb0
commit c20e6edd8a
36 changed files with 552 additions and 157 deletions

View File

@ -41,10 +41,7 @@ Are there any other stages or teams involved that need to be kept in the loop?
the feature can be officially announced in a release blog post.
- [ ] `/chatops run auto_deploy status <merge-commit-of-cleanup-mr>`
- [ ] Close [the feature issue](ISSUE LINK) to indicate the feature will be released in the current milestone.
- [ ] If not already done, clean up the feature flag from all environments by running these chatops command in `#production` channel:
- [ ] `/chatops run feature delete <feature-flag-name> --dev`
- [ ] `/chatops run feature delete <feature-flag-name> --staging`
- [ ] `/chatops run feature delete <feature-flag-name>`
- [ ] If not already done, clean up the feature flag from all environments by running these chatops command in `#production` channel: `/chatops run feature delete <feature-flag-name> --dev --staging --staging-ref --production`
- [ ] Close this rollout issue.

View File

@ -153,6 +153,9 @@ linters:
# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/207950
- Cop/UserAdmin
# See https://gitlab.com/groups/gitlab-org/-/epics/7374.
# This should eventually be enabled
- Gitlab/AvoidGitlabInstanceChecks
RubyComments:
enabled: true

View File

@ -477,6 +477,14 @@ BackgroundMigration/MissingDictionaryFile:
Include:
- 'db/post_migrate/*.rb'
# See https://gitlab.com/groups/gitlab-org/-/epics/7374
Gitlab/AvoidGitlabInstanceChecks:
Enabled: true
Exclude:
- 'db/migrate/*.rb'
- 'db/post_migrate/*.rb'
- 'ee/db/fixtures/**/*'
# See https://gitlab.com/gitlab-org/gitlab/-/issues/373194
Gitlab/RSpec/AvoidSetup:
Enabled: true

View File

@ -0,0 +1,150 @@
---
Gitlab/AvoidGitlabInstanceChecks:
Details: grace period
Exclude:
- 'app/controllers/admin/runners_controller.rb'
- 'app/controllers/explore/groups_controller.rb'
- 'app/controllers/jira_connect/oauth_application_ids_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/helpers/application_settings_helper.rb'
- 'app/helpers/auth_helper.rb'
- 'app/helpers/ci/pipelines_helper.rb'
- 'app/helpers/groups_helper.rb'
- 'app/helpers/integrations_helper.rb'
- 'app/helpers/packages_helper.rb'
- 'app/helpers/projects_helper.rb'
- 'app/helpers/sessions_helper.rb'
- 'app/helpers/sidebars_helper.rb'
- 'app/helpers/users/callouts_helper.rb'
- 'app/helpers/whats_new_helper.rb'
- 'app/mailers/devise_mailer.rb'
- 'app/mailers/emails/in_product_marketing.rb'
- 'app/models/ci/build.rb'
- 'app/models/ci/runner.rb'
- 'app/models/concerns/protected_ref_access.rb'
- 'app/models/container_repository.rb'
- 'app/models/integrations/jira.rb'
- 'app/models/member.rb'
- 'app/models/namespace.rb'
- 'app/models/project.rb'
- 'app/models/release_highlight.rb'
- 'app/policies/base_policy.rb'
- 'app/services/users/signup_service.rb'
- 'app/workers/container_registry/cleanup_worker.rb'
- 'app/workers/container_registry/migration/guard_worker.rb'
- 'app/workers/container_registry/record_data_repair_detail_worker.rb'
- 'app/workers/gitlab_service_ping_worker.rb'
- 'app/workers/users/deactivate_dormant_users_worker.rb'
- 'config/initializers/active_record_transaction_observer.rb'
- 'config/initializers/active_record_transaction_patches.rb'
- 'config/initializers/check_forced_decomposition.rb'
- 'config/initializers/gitlab_experiment.rb'
- 'config/initializers/gitlab_suggested_reviewers_secret.rb'
- 'config/initializers/rack_multipart_patch.rb'
- 'config/initializers/validate_puma.rb'
- 'config/initializers/warden.rb'
- 'ee/app/components/namespaces/storage/limit_alert_component.rb'
- 'ee/app/controllers/admin/namespace_limits_controller.rb'
- 'ee/app/controllers/concerns/ee/onboarding/status.rb'
- 'ee/app/controllers/concerns/onboarding.rb'
- 'ee/app/controllers/concerns/onboarding/set_redirect.rb'
- 'ee/app/controllers/ee/admin/users_controller.rb'
- 'ee/app/controllers/ee/application_controller.rb'
- 'ee/app/controllers/ee/dashboard/projects_controller.rb'
- 'ee/app/controllers/ee/groups/group_members_controller.rb'
- 'ee/app/controllers/ee/search_controller.rb'
- 'ee/app/controllers/sitemap_controller.rb'
- 'ee/app/finders/groups_with_templates_finder.rb'
- 'ee/app/finders/scim_finder.rb'
- 'ee/app/finders/search/elastic_projects_not_indexed_finder.rb'
- 'ee/app/helpers/ee/ci/pipelines_helper.rb'
- 'ee/app/helpers/ee/groups_helper.rb'
- 'ee/app/helpers/ee/namespaces_helper.rb'
- 'ee/app/helpers/ee/projects_helper.rb'
- 'ee/app/helpers/ee/search_helper.rb'
- 'ee/app/helpers/ee/sidebars_helper.rb'
- 'ee/app/helpers/ee/subscribable_banner_helper.rb'
- 'ee/app/helpers/ee/users/callouts_helper.rb'
- 'ee/app/helpers/ee/users_helper.rb'
- 'ee/app/helpers/gitlab_subscriptions/upcoming_reconciliation_helper.rb'
- 'ee/app/helpers/license_helper.rb'
- 'ee/app/helpers/license_monitoring_helper.rb'
- 'ee/app/helpers/trial_registrations_helper.rb'
- 'ee/app/helpers/users/identity_verification_helper.rb'
- 'ee/app/models/ci/minutes/additional_pack.rb'
- 'ee/app/models/ee/application_setting.rb'
- 'ee/app/models/ee/container_repository.rb'
- 'ee/app/models/ee/member.rb'
- 'ee/app/models/ee/namespace.rb'
- 'ee/app/models/ee/namespace_setting.rb'
- 'ee/app/models/ee/plan.rb'
- 'ee/app/models/ee/preloaders/group_policy_preloader.rb'
- 'ee/app/models/ee/preloaders/single_hierarchy_project_group_plans_preloader.rb'
- 'ee/app/models/ee/project.rb'
- 'ee/app/models/ee/project_statistics.rb'
- 'ee/app/models/ee/user.rb'
- 'ee/app/models/gitlab_subscription.rb'
- 'ee/app/models/gitlab_subscriptions/add_on_purchase.rb'
- 'ee/app/models/gitlab_subscriptions/upcoming_reconciliation.rb'
- 'ee/app/models/namespaces/storage/cost_factor.rb'
- 'ee/app/models/namespaces/storage/enforcement.rb'
- 'ee/app/policies/ee/global_policy.rb'
- 'ee/app/policies/ee/group_policy.rb'
- 'ee/app/policies/ee/project_policy.rb'
- 'ee/app/serializers/ee/issue_sidebar_basic_entity.rb'
- 'ee/app/services/ci/minutes/update_project_and_namespace_usage_service.rb'
- 'ee/app/services/ci/runners/stale_group_runners_prune_service.rb'
- 'ee/app/services/ee/notification_service.rb'
- 'ee/app/services/gitlab_subscriptions/activate_service.rb'
- 'ee/app/services/gitlab_subscriptions/add_on_purchases/create_service.rb'
- 'ee/app/services/gitlab_subscriptions/reconciliations/calculate_seat_count_data_service.rb'
- 'ee/app/services/llm/base_service.rb'
- 'ee/app/services/namespaces/service_accounts/create_service.rb'
- 'ee/app/workers/ee/ci/build_finished_worker.rb'
- 'ee/app/workers/elastic_remove_expired_namespace_subscriptions_from_index_cron_worker.rb'
- 'ee/app/workers/gitlab_subscriptions/refresh_seats_worker.rb'
- 'ee/app/workers/gitlab_subscriptions/schedule_refresh_seats_worker.rb'
- 'ee/app/workers/update_all_mirrors_worker.rb'
- 'ee/lib/api/code_suggestions.rb'
- 'ee/lib/api/internal/upcoming_reconciliations.rb'
- 'ee/lib/api/scim/instance_scim.rb'
- 'ee/lib/ee/api/namespaces.rb'
- 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_container_repository_size.rb'
- 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_storage_size_with_recent_size.rb'
- 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_storage_size_without_pipeline_artifacts_size_job.rb'
- 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_storage_size_without_uploads_size.rb'
- 'ee/lib/ee/gitlab/background_migration/create_compliance_standards_adherence.rb'
- 'ee/lib/ee/gitlab/background_migration/migrate_shared_vulnerability_identifiers.rb'
- 'ee/lib/ee/gitlab/gon_helper.rb'
- 'ee/lib/ee/gitlab/saas.rb'
- 'ee/lib/ee/gitlab/scim/base_provisioning_service.rb'
- 'ee/lib/ee/gitlab/snippet_search_results.rb'
- 'ee/lib/ee/gitlab/tracking/standard_context.rb'
- 'ee/lib/ee/sidebars/groups/menus/settings_menu.rb'
- 'ee/lib/gitlab/licenses/submit_license_usage_data_banner.rb'
- 'ee/lib/gitlab/llm/tanuki_bot.rb'
- 'ee/lib/gitlab/manual_quarterly_co_term_banner.rb'
- 'ee/lib/gitlab/sitemaps/generator.rb'
- 'ee/lib/sidebars/groups/menus/trial_widget_menu.rb'
- 'ee/lib/sidebars/user_settings/menus/profile_billing_menu.rb'
- 'ee/lib/tasks/gitlab/elastic.rake'
- 'ee/spec/factories/gitlab_subscriptions.rb'
- 'lib/container_registry/client.rb'
- 'lib/container_registry/gitlab_api_client.rb'
- 'lib/gitlab/background_migration/backfill_project_statistics_storage_size_with_recent_size.rb'
- 'lib/gitlab/content_security_policy/config_loader.rb'
- 'lib/gitlab/database/migration_helpers/convert_to_bigint.rb'
- 'lib/gitlab/database/migration_helpers/wraparound_autovacuum.rb'
- 'lib/gitlab/database/migration_helpers/wraparound_vacuum_helpers.rb'
- 'lib/gitlab/email/message/in_product_marketing/helper.rb'
- 'lib/gitlab/experiment/rollout/feature.rb'
- 'lib/gitlab/gon_helper.rb'
- 'lib/gitlab/monitor/demo_projects.rb'
- 'lib/gitlab/qa.rb'
- 'lib/gitlab/tracking/destinations/database_events_snowplow.rb'
- 'lib/gitlab/tracking/standard_context.rb'
- 'lib/gitlab/usage/metrics/instrumentations/count_ci_internal_pipelines_metric.rb'
- 'lib/gitlab/usage/metrics/instrumentations/count_issues_created_manually_from_alerts_metric.rb'
- 'lib/sidebars/admin/menus/admin_settings_menu.rb'
- 'lib/tasks/gitlab/db/migration_fix_15_11.rake'
- 'spec/helpers/sidebars_helper_spec.rb'

View File

@ -1,6 +1,21 @@
<script>
import { GlButtonGroup, GlButton } from '@gitlab/ui';
const validateOptionsProp = (options) => {
const requiredOptionPropType = {
value: ['string', 'number', 'boolean'],
disabled: ['boolean', 'undefined'],
};
const optionProps = Object.keys(requiredOptionPropType);
return options.every((option) => {
if (!option) {
return false;
}
return optionProps.every((name) => requiredOptionPropType[name].includes(typeof option[name]));
});
};
// TODO: We're planning to move this component to GitLab UI
// https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1787
export default {
@ -12,6 +27,7 @@ export default {
options: {
type: Array,
required: true,
validator: validateOptionsProp,
},
value: {
type: [String, Number, Boolean],

View File

@ -55,6 +55,12 @@ module Pages
strong_memoize_attr :prefix
def unique_host
# When serving custom domain we don't present the unique host to avoid
# GitLab Pages auto-redirect to the unique domain instead of keeping serving
# from the custom domain.
# https://gitlab.com/gitlab-org/gitlab/-/issues/426435
return if domain.present?
url_builder.unique_host
end
strong_memoize_attr :unique_host

View File

@ -93,5 +93,3 @@ module Issuable
end
end
end
Issuable::Clone::BaseService.prepend_mod_with('Issuable::Clone::BaseService')

View File

@ -109,7 +109,7 @@ Commit messages should follow the guidelines below, for reasons explained by Chr
**Important notes:**
- If the guidelines are not met, the MR may not pass the [Danger checks](https://gitlab.com/gitlab-org/gitlab/-/blob/master/danger/commit_messages/Dangerfile).
- If the guidelines are not met, the MR may not pass the [Danger checks](https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/-/blob/master/lib/danger/rules/commit_messages/Dangerfile).
- Consider enabling [Squash and merge](../../user/project/merge_requests/squash_and_merge.md)
if your merge request includes "Applied suggestion to X files" commits, so that Danger can ignore those.
- The prefixes in the form of `[prefix]` and `prefix:` are allowed (they can be all lowercase, as long

View File

@ -4,31 +4,87 @@ group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Sentry
# Sentry monitoring in the frontend development of GitLab
As part of the [Frontend Observability Working Group](https://google.com) we're looking to provide documentation on how to use Sentry effectively.
If left unchecked, Sentry can get noisy and become unreliable.
This page aims to help guide us toward more sensible Sentry usage.
The GitLab Frontend team uses Sentry as an observability tool to monitor how the UI performs for
users on `gitlab.com`. Our Sentry instance is located at
[https://new-sentry.gitlab.net/](https://new-sentry.gitlab.net/). Only GitLab team members can access Sentry.
## Which errors we should report to Sentry explicitly and which should be only shown to users (e.g. as alerts)
GitLab.com is configured to report to our Sentry instance at **Admin > Metrics and profiling > Sentry**.
If we send all errors to Sentry, it gets very noisy, very quickly.
We want to filter out the errors that we either don't care about, or have no control over.
For example, if a user fills out a form incorrectly, this is not something we want to send to Sentry.
If that form fails because it's hitting a dead endpoint, this is an error we want Sentry to know about.
We monitor two kinds of data: **Errors** and **Performance**.
## How to catch errors correctly so Sentry can display them reliably
NOTE:
The [Frontend Observability Working Group](https://handbook.gitlab.com/handbook/company/working-groups/frontend-observability/) is looking to improve how we use Sentry. GitLab team members can provide feedback at
[issue #427402](https://gitlab.com/gitlab-org/gitlab/-/issues/427402).
TBD
## Error reporting
## How to catch special cases you want to track (like we did with the pipeline graph)
Errors, also known as "events" in the Sentry UI, are instances of abnormal or unexpected runtime
behavior that users experience in their browser.
TBD
GitLab uses the [Sentry Browser SDK](https://docs.sentry.io/platforms/javascript/) to report errors
to our Sentry instance under the project
[`gitlabcom-clientside`](https://new-sentry.gitlab.net/organizations/gitlab/projects/gitlabcom-clientside/?project=4).
## How to navigate Sentry and find errors
### Reporting known errors
TBD
The most common way to report errors to Sentry is to call `captureException(error)`, for example:
## How to debug Sentry errors effectively
```javascript
import * as Sentry from '@sentry/browser';
TBD
try {
// Code that may fail in runtime
} catch (error) {
Sentry.captureException(error)
}
```
**When should you report an error?** We want to avoid reporting errors that we either don't care
about, or have no control over. For example, we shouldn't report validation errors when a user fills
out a form incorrectly. However, if that form submission fails because or a server error,
this is an error we want Sentry to know about.
### Unhandled/unknown errors
Additionally, we capture unhandled errors automatically in all of our pages.
## Error Monitoring
Once errors are captured, they appear in Sentry. For example you can see the
[errors reported in the last 24 hours in canary and production](https://new-sentry.gitlab.net/organizations/gitlab/issues/?environment=gprd-cny&environment=gprd&project=4&query=&referrer=issue-list&sort=freq&statsPeriod=24h).
In the list, select any error to see more details... and ideally propose a solution for it!
NOTE:
We suggest filtering errors by the environments `gprd` and `gprd-cny`, as there is some spam in our
environment data.
### Exploring error data
Team members can use Sentry's [Discover page](https://new-sentry.gitlab.net/organizations/gitlab/discover/homepage/?environment=gprd-cny&environment=gprd&field=title&field=event.type&field=project&field=user.display&field=timestamp&field=replayId&name=All+Events&project=4&query=&sort=-timestamp&statsPeriod=14d&yAxis=count%28%29) to find unexpected issues.
Additionally, we have created [a dashboard](https://new-sentry.gitlab.net/organizations/gitlab/dashboard/3/?environment=gprd&environment=gprd-cny&project=4&statsPeriod=24h) to report which feature categories and pages produce
most errors, among other data.
Engineering team members are encouraged to explore error data and find ways to reduce errors on our
user interface. Sentry also provides alerts for folks interested in getting notified when errors occur.
### Filtering errors
We receive several thousands of reports per day, so team members can filter errors based on their
work area.
We mark errors with two additional custom `tags` to help identify their source:
- `feature_category`: The feature area of the page. (For example, `code_review_workflow` or `continuous_integration`.) **Source:** `gon.feature_category`
- `page`: Identifier of method called in the controller to render the page. (For example, `projects:merge_requests:index` or `projects:pipelines:index`.) **Source:** [`body_data_page`](https://gitlab.com/gitlab-org/gitlab/blob/b2ea95b8b1f15228a2fd5fa3fbd316857d5676b8/app/helpers/application_helper.rb#L144).
Frontend engineering team members can filter errors relevant to their group and/or page.
## Performance Monitoring
We use [BrowserTracing](https://docs.sentry.io/platforms/javascript/performance/) to report performance metrics to Sentry.
You can visit [our performance data of the last 24 hours](https://new-sentry.gitlab.net/organizations/gitlab/performance/?environment=gprd-cny&environment=gprd&project=4&statsPeriod=24h) and use the filters to drill down and learn more.

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -6,7 +6,80 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Internal analytics
Learn how to instrument your features on GitLab using:
The internal analytics system provides the ability to track user behavior and system status for a GitLab instance
to inform customer success services and further product development.
- [Service Ping](service_ping/index.md)
- [Snowplow](snowplow/index.md)
These doc pages provide guides and information on how to leverage internal analytics capabilities of GitLab
when developing new features or instrumenting existing ones.
## Fundamental concepts
Events and metrics are the foundation of the internal analytics system.
Understanding the difference between the two concepts is vital to using the system.
### Event
An event is a record of an action that happened within the GitLab instance.
An example action would be a user interaction like visiting the issue page or hovering the mouse cursor over the top navigation search.
Other actions can result from background system processing like scheduled pipeline succeeding or receiving API calls from 3rd party system.
Not every action is tracked and thereby turned into a recorded event automatically.
Instead, if an action helps draw out product insights and helps to make more educated business decisions, we can track an event when the action happens.
The produced event record, at the minimum, holds information that the action occurred,
but it can also contain additional details about the context that accompanied this action.
An example of context can be information about who performed the action or the state of the system at the time of the action.
### Metric
A single event record is not informative enough and might be caused by a coincidence.
We need to look for sets of events sharing common traits to have a foundation for analysis.
This is where metrics come into play. A metric is a calculation performed on pieces of information.
For example, a single event documenting a paid user visiting the feature's page after a new feature was released tells us nothing about the success of this new feature.
However, if we count the number of page view events happening in the week before the new feature release
and then compare it with the number of events for the week following the feature release,
we can derive insights about the increase in interest due to the release of the new feature.
This process leads to what we call a metric. An event-based metric always looks at counts them for a specified time frame, like a week.
The same event can be used across different metrics and a metric can count either one or multiple events.
The count can but does not have to be based on a uniqueness criterion, such as only counting distinct users who performed an event.
Metrics do not have to be based on events. Metrics can also be observations about the state of a GitLab instance itself,
such as the value of a setting or the count of rows in a database table.
## Data flow
For GitLab there is an essential difference in analytics setup between SaaS and self-managed or GitLab Dedicated instances.
On SaaS event records are directly sent to a collection system, called Snowplow, and imported into our data warehouse.
Self-managed and GitLab Dedicated instances record event counts locally. Every week, a process called Service Ping sends the current
values for all pre-defined and active metrics to our data warehouse. For GitLab.com, metrics are calculated directly in the data warehouse.
The following chart aims to illustrate this data flow:
```mermaid
flowchart LR;
feature-->track
track-->|send event record - only on gitlab.com|snowplow
track-->|increase metric counts|redis
database-->service_ping
redis-->service_ping
service_ping-->|json with metric values - weekly export|snowflake
snowplow-->|event records - continuous import|snowflake
snowflake-->vis
subgraph glb[Gitlab Application]
feature[Feature Code]
subgraph events[Internal Analytics Code]
track[track_event / trackEvent]
redis[(Redis)]
database[(Database)]
service_ping[\Service Ping Process\]
end
end
snowplow[\Snowplow Pipeline\]
snowflake[(Data Warehouse)]
vis[Dashboards in Sisense/Tableau]
```
## Instrumentation
- To instrument an event-based metric, please look into the [internal event tracking quick start guide](internal_event_instrumentation/quick_start.md).
- To instrument a metric that observes the GitLab instances state, please start with [the service ping implementation](service_ping/implement.md).

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -46,7 +46,7 @@ Running `yarn jest-debug` runs Jest in debug mode, allowing you to debug/inspect
### Timeout error
The default timeout for Jest is set in
[`/spec/frontend/test_setup.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/frontend/test_setup.js).
[`/jest.config.base.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/jest.config.base.js).
If your test exceeds that time, it fails.

View File

@ -1,5 +1,5 @@
---
stage: Data Science
stage: Govern
group: Anti-Abuse
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -38,7 +38,7 @@ GitLab is creating AI-assisted features across our DevSecOps platform. These fea
- This setting is available to Ultimate groups on SaaS and can be
set by a user who has the Owner role in the group.
- View [how to enable this setting](group/manage.md#enable-third-party-ai-features).
- Experiment features
- Experiment and Beta features
- All features categorized as
[Experiment features](../policy/experiment-beta-support.md#experiment) or
[Beta features](../policy/experiment-beta-support.md#beta)
@ -46,10 +46,10 @@ GitLab is creating AI-assisted features across our DevSecOps platform. These fea
level. This is in addition to the Third-party AI features setting.
- Their usage is subject to the
[Testing Terms of Use](https://about.gitlab.com/handbook/legal/testing-agreement/).
- Experiment features are disabled by default.
- Experiment and Beta features are disabled by default.
- This setting is available to Ultimate groups on SaaS and can be set by a user
who has the Owner role in the group.
- View [how to enable this setting](group/manage.md#enable-experiment-features).
- View [how to enable this setting](group/manage.md#enable-experiment-and-beta-features).
- Code Suggestions
- View [how to enable for self-managed](project/repository/code_suggestions/saas.md#enable-code-suggestions).
- View [how to enable for SaaS](project/repository/code_suggestions/self_managed.md#enable-code-suggestions-on-self-managed-gitlab).
@ -66,7 +66,7 @@ To use this feature:
- The parent group of the project must:
- Enable the [third-party AI features setting](group/manage.md#enable-third-party-ai-features).
- Enable the [experiment features setting](group/manage.md#enable-experiment-features).
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
- You must be a member of the project with sufficient permissions to view the repository.
GitLab can help you get up to speed faster if you:
@ -111,7 +111,7 @@ We cannot guarantee that the large language model produces results that are corr
To use this feature, at least one group you're a member of must:
- Have the [third-party AI features setting](group/manage.md#enable-third-party-ai-features) enabled.
- Have the [experiment features setting](group/manage.md#enable-experiment-features) enabled.
- Have the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
You can get AI generated support from GitLab Duo Chat about the following topics:
@ -158,7 +158,7 @@ To use this feature:
- The parent group of the issue must:
- Enable the [third-party AI features setting](group/manage.md#enable-third-party-ai-features).
- Enable the [experiment features setting](group/manage.md#enable-experiment-features).
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
- You must be a member of the project with sufficient permissions to view the issue.
You can generate a summary of discussions on an issue:
@ -182,7 +182,7 @@ To use this feature:
- The parent group of the project must:
- Enable the [third-party AI features setting](group/manage.md#enable-third-party-ai-features).
- Enable the [experiment features setting](group/manage.md#enable-experiment-features).
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
- You must be a member of the project with sufficient permissions to view the CI/CD analytics.
In CI/CD Analytics, you can view a forecast of deployment frequency:
@ -208,7 +208,7 @@ To use this feature:
- The parent group of the project must:
- Enable the [third-party AI features setting](group/manage.md#enable-third-party-ai-features).
- Enable the [experiment features setting](group/manage.md#enable-experiment-features).
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
- You must be a member of the project with sufficient permissions to view the CI/CD job.
When the feature is available, the "Root cause analysis" button will appears on
@ -223,7 +223,7 @@ To use this feature:
- The parent group of the project must:
- Enable the [third-party AI features setting](group/manage.md#enable-third-party-ai-features).
- Enable the [experiment features setting](group/manage.md#enable-experiment-features).
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
- You must be a member of the project with sufficient permissions to view the issue.
You can generate the description for an issue from a short summary.

View File

@ -464,16 +464,16 @@ To update this setting:
1. Under **Code Suggestions**, select the **Projects in this group can use Code Suggestions** checkbox.
1. Select **Save changes**.
## Enable Experiment features **(ULTIMATE SAAS)**
## Enable Experiment and Beta features **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118222) in GitLab 16.0.
WARNING:
[Experiment features](../../policy/experiment-beta-support.md#experiment) may produce unexpected results
[Experiment and Beta features](../../policy/experiment-beta-support.md) may produce unexpected results
(for example, the results might be low-quality, incomplete, incoherent, offensive, or insensitive,
and might include insecure code or failed pipelines).
You can give all users in a top-level group access to Experiment features.
You can give all users in a top-level group access to Experiment and Beta features.
This setting [cascades to all projects](../project/merge_requests/approvals/settings.md#settings-cascading)
that belong to the group.
@ -482,7 +482,7 @@ To enable Experiment features for a top-level group:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > General**.
1. Expand **Permissions and group features**.
1. Under **Experiment features**, select the **Use Experiment features** checkbox.
1. Under **Experiment and Beta features**, select the **Use Experiment and Beta features** checkbox.
1. Select **Save changes**.
## Enable third-party AI features **(ULTIMATE SAAS)**

View File

@ -6,6 +6,8 @@ module Gitlab
# Sometimes it's not clear which of not implemented interfaces caused this error.
# We need custom exception to be able to add text that gives extra context.
NotImplementedError = Class.new(StandardError)
NoteableNotFound = Class.new(StandardError)
end
end
end

View File

@ -36,13 +36,6 @@ module Gitlab
Logger.warn(message: e.message, 'error.class': e.class.name)
import_with_legacy_diff_note
rescue ActiveRecord::InvalidForeignKey => e
# It's possible the project and the issue have been deleted since
# scheduling this job. In this case we'll just skip creating the note
Logger.info(
message: e.message,
github_identifiers: note.github_identifiers
)
end
private

View File

@ -64,9 +64,6 @@ module Gitlab
issue.validate!
insert_and_return_id(attributes, project.issues)
rescue ActiveRecord::InvalidForeignKey
# It's possible the project has been deleted since scheduling this
# job. In this case we'll just skip creating the issue.
end
# Stores all issue assignees in the database.

View File

@ -17,7 +17,9 @@ module Gitlab
end
def execute
return unless (noteable_id = find_noteable_id)
noteable_id = find_noteable_id
raise Exceptions::NoteableNotFound, 'Error to find noteable_id for note' unless noteable_id
author_id, author_found = user_finder.author_id_for(note)
@ -34,8 +36,7 @@ module Gitlab
updated_at: note.updated_at
}
note = Note.new(attributes.merge(importing: true))
note.validate!
Note.new(attributes.merge(importing: true)).validate!
# We're using bulk_insert here so we can bypass any callbacks.
# Running these would result in a lot of unnecessary SQL
@ -44,9 +45,6 @@ module Gitlab
# to generate HTML version - you also need to regenerate it in
# Gitlab::GithubImport::Importer::NoteAttachmentsImporter.
ApplicationRecord.legacy_bulk_insert(Note.table_name, [attributes]) # rubocop:disable Gitlab/BulkInsert
rescue ActiveRecord::InvalidForeignKey
# It's possible the project and the issue have been deleted since
# scheduling this job. In this case we'll just skip creating the note.
end
# Returns the ID of the issue or merge request to create the note for.

View File

@ -5429,16 +5429,13 @@ msgstr ""
msgid "Analytics|Charts"
msgstr ""
msgid "Analytics|Choose a chart type on the right"
msgstr ""
msgid "Analytics|Choose a measurement to start"
msgstr ""
msgid "Analytics|Code"
msgstr ""
msgid "Analytics|Column Chart"
msgid "Analytics|Column chart"
msgstr ""
msgid "Analytics|Configure Dashboard Project"
@ -5477,7 +5474,7 @@ msgstr ""
msgid "Analytics|Data"
msgstr ""
msgid "Analytics|Data Table"
msgid "Analytics|Data table"
msgstr ""
msgid "Analytics|Dates and times are displayed in the UTC timezone"
@ -5513,7 +5510,7 @@ msgstr ""
msgid "Analytics|Language"
msgstr ""
msgid "Analytics|Line Chart"
msgid "Analytics|Line chart"
msgstr ""
msgid "Analytics|New dashboard"
@ -5564,7 +5561,7 @@ msgstr ""
msgid "Analytics|Select a visualization type"
msgstr ""
msgid "Analytics|Single Statistic"
msgid "Analytics|Single statistic"
msgstr ""
msgid "Analytics|Single stats"
@ -5615,15 +5612,15 @@ msgstr ""
msgid "Analytics|Visualization Designer"
msgstr ""
msgid "Analytics|Visualization Type"
msgstr ""
msgid "Analytics|Visualization designer"
msgstr ""
msgid "Analytics|Visualization title"
msgstr ""
msgid "Analytics|Visualization type"
msgstr ""
msgid "Analytics|Visualization was saved successfully"
msgstr ""
@ -10098,9 +10095,6 @@ msgstr ""
msgid "Ci config already present"
msgstr ""
msgid "CiCatalog|About this project"
msgstr ""
msgid "CiCatalog|Back to the CI/CD Catalog"
msgstr ""

View File

@ -0,0 +1,54 @@
# frozen_string_literal: true
require 'rubocop-rspec'
module RuboCop
module Cop
module Gitlab
# This cop checks for use of gitlab instance specific checks.
#
# @example
#
# # bad
# if Gitlab.com?
# Ci::Runner::FORM_EDITABLE + Ci::Runner::MINUTES_COST_FACTOR_FIELDS
# else
# Ci::Runner::FORM_EDITABLE
# end
#
# # good
# if Gitlab::Saas.feature_available?('purchases/additional_minutes')
# Ci::Runner::FORM_EDITABLE + Ci::Runner::MINUTES_COST_FACTOR_FIELDS
# else
# Ci::Runner::FORM_EDITABLE
# end
#
class AvoidGitlabInstanceChecks < RuboCop::Cop::Base
MSG = 'Avoid the use of `%{name}`. Use Gitlab::Saas.feature_available?. ' \
'See https://docs.gitlab.com/ee/development/ee_features.html#saas-only-feature'
RESTRICT_ON_SEND = %i[
com? com_except_jh? com_and_canary? com_but_not_canary? org_or_com? should_check_namespace_plan?
].freeze
# @!method gitlab?(node)
def_node_matcher :gitlab?, <<~PATTERN
(send (const {nil? (cbase)} :Gitlab) ...)
PATTERN
# @!method should_check_namespace_plan?(node)
def_node_matcher :should_check_namespace_plan?, <<~PATTERN
(send
(const
(const
{nil? (cbase)} :Gitlab) :CurrentSettings) :should_check_namespace_plan?)
PATTERN
def on_send(node)
return unless gitlab?(node) || should_check_namespace_plan?(node)
add_offense(node, message: format(MSG, name: node.method_name))
end
end
end
end
end

View File

@ -14,7 +14,7 @@ function retry_times_sleep() {
for i in $(seq "${number_of_retries}" -1 1); do
sleep "$sleep_seconds"s
echo "[$(date '+%H:%M:%S')] Retrying $i..."
echo "[$(date '+%H:%M:%S')] Retry attempts left: $i..."
if eval "$@"; then
return 0
fi
@ -54,6 +54,7 @@ function test_url() {
status=$(eval "${cmd}")
if [[ $status == "200" ]]; then
echo -e "\n[$(date '+%H:%M:%S')] Curl to $url successful with 200 response"
return 0
else
# We display the error in the job to allow for better debugging

View File

@ -10,6 +10,7 @@ const DEFAULT_OPTIONS = [
];
describe('~/vue_shared/components/segmented_control_button_group.vue', () => {
let consoleSpy;
let wrapper;
const createComponent = (props = {}, scopedSlots = {}) => {
@ -97,4 +98,34 @@ describe('~/vue_shared/components/segmented_control_button_group.vue', () => {
);
});
});
describe('options prop validation', () => {
beforeEach(() => {
consoleSpy = jest.spyOn(console, 'error').mockImplementation();
});
it.each([
[[{ disabled: true }]],
[[{ value: '1', disabled: 'false' }]],
[[{ value: null, disabled: 'true' }]],
[[[{ value: true }, null]]],
])('with options=%j, fails validation', (options) => {
createComponent({ options });
expect(consoleSpy).toHaveBeenCalledTimes(1);
expect(consoleSpy).toHaveBeenCalledWith(
expect.stringContaining('Invalid prop: custom validator check failed for prop "options"'),
);
});
it.each([
[[{ value: '1' }]],
[[{ value: 1, disabled: true }]],
[[{ value: true, disabled: false }]],
])('with options=%j, passes validation', (options) => {
createComponent({ options });
expect(consoleSpy).not.toHaveBeenCalled();
});
});
});

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_failures do
RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_failures, feature_category: :importers do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
@ -80,17 +80,6 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail
expect(note.author_id).to eq(project.creator_id)
expect(note.note).to eq("*Created by: #{user.username}*\n\nHello")
end
it 'does not import the note when a foreign key error is raised' do
stub_user_finder(project.creator_id, false)
expect(ApplicationRecord)
.to receive(:legacy_bulk_insert)
.and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key')
expect { subject.execute }
.not_to change(LegacyDiffNote, :count)
end
end
describe '#execute' do

View File

@ -183,21 +183,6 @@ RSpec.describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redi
end
end
context 'when the import fails due to a foreign key error' do
it 'does not raise any errors' do
allow(importer.user_finder)
.to receive(:author_id_for)
.with(issue)
.and_return([user.id, true])
expect(importer)
.to receive(:insert_and_return_id)
.and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key')
expect { importer.create_issue }.not_to raise_error
end
end
it 'produces a valid Issue' do
allow(importer.user_finder)
.to receive(:author_id_for)

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::GithubImport::Importer::NoteImporter do
RSpec.describe Gitlab::GithubImport::Importer::NoteImporter, feature_category: :importers do
let(:client) { double(:client) }
let(:project) { create(:project) }
let(:user) { create(:user) }
@ -12,13 +12,13 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteImporter do
let(:github_note) do
Gitlab::GithubImport::Representation::Note.new(
note_id: 100,
noteable_id: 1,
noteable_type: 'Issue',
author: Gitlab::GithubImport::Representation::User.new(id: 4, login: 'alice'),
note: note_body,
created_at: created_at,
updated_at: updated_at,
github_id: 1
updated_at: updated_at
)
end
@ -128,34 +128,20 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteImporter do
expect { importer.execute }.to raise_error(ActiveRecord::RecordInvalid)
end
end
end
context 'when the noteable does not exist' do
it 'does not import the note' do
expect(ApplicationRecord).not_to receive(:legacy_bulk_insert)
context 'when noteble_id can not be found' do
before do
allow(importer)
.to receive(:find_noteable_id)
.and_return(nil)
end
importer.execute
end
end
context 'when the import fails due to a foreign key error' do
it 'does not raise any errors' do
issue_row = create(:issue, project: project, iid: 1)
allow(importer)
.to receive(:find_noteable_id)
.and_return(issue_row.id)
allow(importer.user_finder)
.to receive(:author_id_for)
.with(github_note)
.and_return([user.id, true])
expect(ApplicationRecord)
.to receive(:legacy_bulk_insert)
.and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key')
expect { importer.execute }.not_to raise_error
it 'raises NoteableNotFound' do
expect { importer.execute }.to raise_error(
::Gitlab::GithubImport::Exceptions::NoteableNotFound,
'Error to find noteable_id for note'
)
end
end
end
@ -175,13 +161,6 @@ RSpec.describe Gitlab::GithubImport::Importer::NoteImporter do
expect(project.notes.take).to be_valid
end
# rubocop:disable RSpec/AnyInstanceOf
it 'skips markdown field cache callback' do
expect_any_instance_of(Note).not_to receive(:refresh_markdown_cache)
importer.execute
end
# rubocop:enable RSpec/AnyInstanceOf
end
describe '#find_noteable_id' do

View File

@ -126,6 +126,9 @@ RSpec.describe SwapNotesIdToBigintForSelfManaged, feature_category: :database do
after do
connection.execute('ALTER TABLE system_note_metadata DROP CONSTRAINT IF EXISTS fk_rails_d83a918cb1')
connection.execute('ALTER TABLE system_note_metadata DROP CONSTRAINT IF EXISTS fk_d83a918cb1_tmp')
connection.execute('ALTER TABLE system_note_metadata ADD CONSTRAINT fk_d83a918cb1 FOREIGN KEY (note_id)
REFERENCES notes(id) ON DELETE CASCADE')
end
it 'swaps the columns' do

View File

@ -4,8 +4,10 @@ require 'spec_helper'
RSpec.describe Pages::LookupPath, feature_category: :pages do
let(:project) { create(:project, :pages_private, pages_https_only: true) }
let(:trim_prefix) { nil }
let(:domain) { nil }
subject(:lookup_path) { described_class.new(project) }
subject(:lookup_path) { described_class.new(project, trim_prefix: trim_prefix, domain: domain) }
before do
stub_pages_setting(
@ -30,11 +32,7 @@ RSpec.describe Pages::LookupPath, feature_category: :pages do
end
describe '#https_only' do
subject(:lookup_path) { described_class.new(project, domain: domain) }
context 'when no domain provided' do
let(:domain) { nil }
it 'delegates to Project#pages_https_only?' do
expect(lookup_path.https_only).to eq(true)
end
@ -124,18 +122,22 @@ RSpec.describe Pages::LookupPath, feature_category: :pages do
end
describe '#prefix' do
it 'returns "/" for pages group root projects' do
project = instance_double(Project, full_path: "namespace/namespace.example.com")
lookup_path = described_class.new(project, trim_prefix: 'mygroup')
let(:trim_prefix) { 'mygroup' }
expect(lookup_path.prefix).to eq('/')
context 'when pages group root projects' do
let(:project) { instance_double(Project, full_path: "namespace/namespace.example.com") }
it 'returns "/"' do
expect(lookup_path.prefix).to eq('/')
end
end
it 'returns the project full path with the provided prefix removed' do
project = instance_double(Project, full_path: 'mygroup/myproject')
lookup_path = described_class.new(project, trim_prefix: 'mygroup')
context 'when pages in the given prefix' do
let(:project) { instance_double(Project, full_path: 'mygroup/myproject') }
expect(lookup_path.prefix).to eq('/myproject/')
it 'returns the project full path with the provided prefix removed' do
expect(lookup_path.prefix).to eq('/myproject/')
end
end
end
@ -157,12 +159,18 @@ RSpec.describe Pages::LookupPath, feature_category: :pages do
expect(lookup_path.unique_host).to eq('unique-domain.example.com')
end
context 'when there is domain provided' do
let(:domain) { instance_double(PagesDomain) }
it 'returns nil' do
expect(lookup_path.unique_host).to eq(nil)
end
end
end
end
describe '#root_directory' do
subject(:lookup_path) { described_class.new(project) }
context 'when there is no deployment' do
it 'returns nil' do
expect(lookup_path.root_directory).to be_nil

View File

@ -69,6 +69,15 @@ RSpec.describe API::Internal::Pages, feature_category: :pages do
context 'when querying a custom domain' do
let_it_be(:pages_domain) { create(:pages_domain, domain: 'pages.io', project: project) }
# We need to ensure not to return the unique domain when requesting a custom domain
# https://gitlab.com/gitlab-org/gitlab/-/issues/426435
before_all do
project.project_setting.update!(
pages_unique_domain: 'unique-domain',
pages_unique_domain_enabled: true
)
end
context 'when there are no pages deployed for the related project' do
before do
project.mark_pages_as_not_deployed

View File

@ -0,0 +1,45 @@
# frozen_string_literal: true
require 'rubocop_spec_helper'
require 'rspec-parameterized'
require_relative '../../../../rubocop/cop/gitlab/avoid_gitlab_instance_checks'
RSpec.describe RuboCop::Cop::Gitlab::AvoidGitlabInstanceChecks, feature_category: :shared do
let(:msg) { described_class::MSG }
describe 'bad examples' do
where(:code) do
%w[
Gitlab.com?
Gitlab.com_except_jh?
Gitlab.com_and_canary?
Gitlab.com_but_not_canary?
Gitlab.org_or_com?
::Gitlab.com?
Gitlab::CurrentSettings.should_check_namespace_plan?
::Gitlab::CurrentSettings.should_check_namespace_plan?
]
end
with_them do
it 'registers an offense' do
expect_offense(<<~CODE, node: code)
return if %{node}
^{node} Avoid the use of [...]
CODE
end
end
end
describe 'good examples' do
where(:code) do
%w[com? com Gitlab.com Gitlab::CurrentSettings.check_namespace_plan?]
end
with_them do
it 'does not register an offense' do
expect_no_offenses(code)
end
end
end
end