mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-07-29 12:00:32 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -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.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
150
.rubocop_todo/gitlab/avoid_gitlab_instance_checks.yml
Normal file
150
.rubocop_todo/gitlab/avoid_gitlab_instance_checks.yml
Normal 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'
|
@ -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],
|
||||
|
@ -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
|
||||
|
@ -93,5 +93,3 @@ module Issuable
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Issuable::Clone::BaseService.prepend_mod_with('Issuable::Clone::BaseService')
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
---
|
||||
|
@ -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.
|
||||
|
@ -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)**
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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 ""
|
||||
|
||||
|
54
rubocop/cop/gitlab/avoid_gitlab_instance_checks.rb
Normal file
54
rubocop/cop/gitlab/avoid_gitlab_instance_checks.rb
Normal 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
|
@ -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
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
45
spec/rubocop/cop/gitlab/avoid_gitlab_instance_checks_spec.rb
Normal file
45
spec/rubocop/cop/gitlab/avoid_gitlab_instance_checks_spec.rb
Normal 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
|
Reference in New Issue
Block a user