Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
058e1a233f
commit
b0d4724e47
|
@ -1 +1 @@
|
||||||
88f78ed883808636f3ee02601ee37f944c82b07e
|
a46121713a40b8c30794009eb4c40864a089e5a6
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
return this.getUserData;
|
return this.getUserData;
|
||||||
},
|
},
|
||||||
mappedLines() {
|
mappedLines() {
|
||||||
// TODO: Do this data generation when we recieve a response to save a computed property being created
|
// TODO: Do this data generation when we receive a response to save a computed property being created
|
||||||
return this.diffLines(this.diffFile).map(mapParallel(this)) || [];
|
return this.diffLines(this.diffFile).map(mapParallel(this)) || [];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,7 +36,7 @@ export const registerExtension = (extension) => {
|
||||||
(acc, computedKey) => ({
|
(acc, computedKey) => ({
|
||||||
...acc,
|
...acc,
|
||||||
// Making the computed property a method allows us to pass in arguments
|
// Making the computed property a method allows us to pass in arguments
|
||||||
// this allows for each computed property to recieve some data
|
// this allows for each computed property to receive some data
|
||||||
[computedKey]() {
|
[computedKey]() {
|
||||||
return extension.computed[computedKey];
|
return extension.computed[computedKey];
|
||||||
},
|
},
|
||||||
|
|
|
@ -100,6 +100,8 @@ $monokai-gh: #75715e;
|
||||||
// We should be able to remove the overrides once the upstream issue is fixed (https://github.com/sourcegraph/sourcegraph/issues/23251)
|
// We should be able to remove the overrides once the upstream issue is fixed (https://github.com/sourcegraph/sourcegraph/issues/23251)
|
||||||
@include hljs-override('string', $monokai-s);
|
@include hljs-override('string', $monokai-s);
|
||||||
@include hljs-override('attr', $monokai-na);
|
@include hljs-override('attr', $monokai-na);
|
||||||
|
@include hljs-override('attribute', $monokai-n);
|
||||||
|
@include hljs-override('selector-tag', $monokai-nt);
|
||||||
@include hljs-override('keyword', $monokai-k);
|
@include hljs-override('keyword', $monokai-k);
|
||||||
@include hljs-override('variable', $monokai-nv);
|
@include hljs-override('variable', $monokai-nv);
|
||||||
@include hljs-override('variable.language_', $monokai-k);
|
@include hljs-override('variable.language_', $monokai-k);
|
||||||
|
|
|
@ -103,6 +103,8 @@ $solarized-dark-il: #2aa198;
|
||||||
// We should be able to remove the overrides once the upstream issue is fixed (https://github.com/sourcegraph/sourcegraph/issues/23251)
|
// We should be able to remove the overrides once the upstream issue is fixed (https://github.com/sourcegraph/sourcegraph/issues/23251)
|
||||||
@include hljs-override('string', $solarized-dark-s);
|
@include hljs-override('string', $solarized-dark-s);
|
||||||
@include hljs-override('attr', $solarized-dark-na);
|
@include hljs-override('attr', $solarized-dark-na);
|
||||||
|
@include hljs-override('attribute', $solarized-dark-n);
|
||||||
|
@include hljs-override('selector-tag', $solarized-dark-nt);
|
||||||
@include hljs-override('keyword', $solarized-dark-k);
|
@include hljs-override('keyword', $solarized-dark-k);
|
||||||
@include hljs-override('variable', $solarized-dark-nv);
|
@include hljs-override('variable', $solarized-dark-nv);
|
||||||
@include hljs-override('variable.language_', $solarized-dark-k);
|
@include hljs-override('variable.language_', $solarized-dark-k);
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
group_link = @project.project_group_links.find(params[:id])
|
group_link = @project.project_group_links.find(params[:id])
|
||||||
Projects::GroupLinks::UpdateService.new(group_link).execute(group_link_params)
|
Projects::GroupLinks::UpdateService.new(group_link, current_user).execute(group_link_params)
|
||||||
|
|
||||||
if group_link.expires?
|
if group_link.expires?
|
||||||
render json: {
|
render json: {
|
||||||
|
|
|
@ -37,3 +37,5 @@ module Projects
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Projects::GroupLinks::UpdateService.prepend_mod
|
||||||
|
|
|
@ -131,11 +131,24 @@ class PostReceive
|
||||||
repository_update_hook_data = Gitlab::DataBuilder::Repository.update(project, user, changes, refs)
|
repository_update_hook_data = Gitlab::DataBuilder::Repository.update(project, user, changes, refs)
|
||||||
SystemHooksService.new.execute_hooks(repository_update_hook_data, :repository_update_hooks)
|
SystemHooksService.new.execute_hooks(repository_update_hook_data, :repository_update_hooks)
|
||||||
Gitlab::UsageDataCounters::SourceCodeCounter.count(:pushes)
|
Gitlab::UsageDataCounters::SourceCodeCounter.count(:pushes)
|
||||||
|
emit_snowplow_event(project, user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def log(message)
|
def log(message)
|
||||||
Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
|
Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emit_snowplow_event(project, user)
|
||||||
|
return unless Feature.enabled?(:route_hll_to_snowplow_phase2, project.namespace)
|
||||||
|
|
||||||
|
Gitlab::Tracking.event(
|
||||||
|
'PostReceive',
|
||||||
|
'source_code_pushes',
|
||||||
|
project: project,
|
||||||
|
namespace: project.namespace,
|
||||||
|
user: user
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
PostReceive.prepend_mod_with('PostReceive')
|
PostReceive.prepend_mod_with('PostReceive')
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
description: Issue was added to an epic
|
||||||
|
category: issues_edit
|
||||||
|
action: g_project_management_issue_added_to_epic
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: plan
|
||||||
|
product_group: project_management
|
||||||
|
product_category: issue_tracking
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
|
||||||
|
distributions:
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
description: Epic was changed on an issue
|
||||||
|
category: issues_edit
|
||||||
|
action: g_project_management_issue_changed_epic
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: plan
|
||||||
|
product_group: project_management
|
||||||
|
product_category: issue_tracking
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
|
||||||
|
distributions:
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
description: Health status was changed on an issue
|
||||||
|
category: issues_edit
|
||||||
|
action: g_project_management_issue_health_status_changed
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: plan
|
||||||
|
product_group: project_management
|
||||||
|
product_category: issue_tracking
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
|
||||||
|
distributions:
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
description: Issue's iteration was changed
|
||||||
|
category: issues_edit
|
||||||
|
action: g_project_management_issue_iteration_changed
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: plan
|
||||||
|
product_group: project_management
|
||||||
|
product_category: issue_tracking
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
|
||||||
|
distributions:
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
description: An issue was removed from an epic
|
||||||
|
category: issues_edit
|
||||||
|
action: g_project_management_issue_removed_from_epic
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: plan
|
||||||
|
product_group: project_management
|
||||||
|
product_category: issue_tracking
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
|
||||||
|
distributions:
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
description: Issue's weight was changed
|
||||||
|
category: issues_edit
|
||||||
|
action: g_project_management_issue_weight_changed
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: plan
|
||||||
|
product_group: project_management
|
||||||
|
product_category: issue_tracking
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
|
||||||
|
distributions:
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
description: All events of Git push operations
|
||||||
|
category: PostReceive
|
||||||
|
action: source_code_pushes
|
||||||
|
label_description:
|
||||||
|
property_description:
|
||||||
|
value_description:
|
||||||
|
extra_properties:
|
||||||
|
identifiers:
|
||||||
|
- project
|
||||||
|
- user
|
||||||
|
- namespace
|
||||||
|
product_section: dev
|
||||||
|
product_stage: create
|
||||||
|
product_group: source_code
|
||||||
|
product_category: source_code_management
|
||||||
|
milestone: "15.2"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91605
|
||||||
|
distributions:
|
||||||
|
- ce
|
||||||
|
- ee
|
||||||
|
tiers:
|
||||||
|
- free
|
||||||
|
- premium
|
||||||
|
- ultimate
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
data_category: optional
|
data_category: optional
|
||||||
key_path: grafana_link_enabled
|
key_path: grafana_link_enabled
|
||||||
description: Whether Grafana is enabled
|
description: Whether Grafana is enabled
|
||||||
product_section: growth
|
product_section: ops
|
||||||
product_stage: growth
|
product_stage: monitor
|
||||||
product_group: product_intelligence
|
product_group: respond
|
||||||
product_category: collection
|
product_category: collection
|
||||||
value_type: boolean
|
value_type: boolean
|
||||||
status: active
|
status: active
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class BackfillImportedIssueSearchData < Gitlab::Database::Migration[2.0]
|
class BackfillImportedIssueSearchData < Gitlab::Database::Migration[2.0]
|
||||||
disable_ddl_transaction!
|
|
||||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
|
||||||
|
|
||||||
MIGRATION = 'BackfillImportedIssueSearchData'
|
|
||||||
DELAY_INTERVAL = 120.seconds
|
|
||||||
|
|
||||||
def up
|
def up
|
||||||
min_value = Gitlab::Database::BackgroundMigration::BatchedMigration.find_by(
|
# replaced by 20220707075300_reschedule_backfill_imported_issue_search_data.rb
|
||||||
job_class_name: "BackfillIssueSearchData"
|
|
||||||
)&.max_value || BATCH_MIN_VALUE
|
|
||||||
queue_batched_background_migration(
|
|
||||||
MIGRATION,
|
|
||||||
:issues,
|
|
||||||
:id,
|
|
||||||
job_interval: DELAY_INTERVAL,
|
|
||||||
batch_min_value: min_value
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
delete_batched_background_migration(MIGRATION, :issues, :id, [])
|
# replaced by 20220707075300_reschedule_backfill_imported_issue_search_data.rb
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ScheduleDisableLegacyOpenSourceLicenseForInactivePublicProjects < Gitlab::Database::Migration[2.0]
|
||||||
|
MIGRATION = 'DisableLegacyOpenSourceLicenseForInactivePublicProjects'
|
||||||
|
INTERVAL = 2.minutes
|
||||||
|
BATCH_SIZE = 1_000
|
||||||
|
MAX_BATCH_SIZE = 5_000
|
||||||
|
SUB_BATCH_SIZE = 200
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||||
|
|
||||||
|
def up
|
||||||
|
return unless Gitlab.com?
|
||||||
|
|
||||||
|
queue_batched_background_migration(
|
||||||
|
MIGRATION,
|
||||||
|
:projects,
|
||||||
|
:id,
|
||||||
|
job_interval: INTERVAL,
|
||||||
|
batch_size: BATCH_SIZE,
|
||||||
|
max_batch_size: MAX_BATCH_SIZE,
|
||||||
|
sub_batch_size: SUB_BATCH_SIZE
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
return unless Gitlab.com?
|
||||||
|
|
||||||
|
delete_batched_background_migration(MIGRATION, :projects, :id, [])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,35 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class RescheduleBackfillImportedIssueSearchData < Gitlab::Database::Migration[2.0]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||||
|
|
||||||
|
MIGRATION = 'BackfillImportedIssueSearchData'
|
||||||
|
DELAY_INTERVAL = 120.seconds
|
||||||
|
BATCH_SIZE = 50_000
|
||||||
|
SUB_BATCH_SIZE = 1_000
|
||||||
|
|
||||||
|
def up
|
||||||
|
# remove the original migration
|
||||||
|
delete_batched_background_migration(MIGRATION, :issues, :id, [])
|
||||||
|
|
||||||
|
# reschedule the migration
|
||||||
|
min_value = Gitlab::Database::BackgroundMigration::BatchedMigration.find_by(
|
||||||
|
job_class_name: "BackfillIssueSearchData"
|
||||||
|
)&.max_value || BATCH_MIN_VALUE
|
||||||
|
|
||||||
|
queue_batched_background_migration(
|
||||||
|
MIGRATION,
|
||||||
|
:issues,
|
||||||
|
:id,
|
||||||
|
job_interval: DELAY_INTERVAL,
|
||||||
|
batch_min_value: min_value,
|
||||||
|
batch_size: BATCH_SIZE,
|
||||||
|
sub_batch_size: SUB_BATCH_SIZE
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
delete_batched_background_migration(MIGRATION, :issues, :id, [])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
e0038cb5687098e93a250e6fb0449d0ae2eb7c534219b3f24a9258f2a3c0fedb
|
|
@ -0,0 +1 @@
|
||||||
|
f796c973e95ad95fb95e72214ba664382757c5127bdd19b00934bf99b394fde3
|
|
@ -604,3 +604,117 @@ X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
|
||||||
"event_type": "project_fork_operation"
|
"event_type": "project_fork_operation"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Audit event streaming on project group link actions
|
||||||
|
|
||||||
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90955) in GitLab 15.2.
|
||||||
|
|
||||||
|
Stream audit events that relate to project group link creation, updates, and deletion using the `/logs` endpoint.
|
||||||
|
|
||||||
|
Send API requests that contain the `X-Gitlab-Audit-Event-Type` header with value of either:
|
||||||
|
|
||||||
|
- `project_group_link_create`.
|
||||||
|
- `project_group_link_update`.
|
||||||
|
- `project_group_link_destroy`.
|
||||||
|
|
||||||
|
GitLab responds with JSON payloads with an `event_type` field set to either:
|
||||||
|
|
||||||
|
- `project_group_link_create`.
|
||||||
|
- `project_group_link_update`.
|
||||||
|
- `project_group_link_destroy`.
|
||||||
|
|
||||||
|
### Example Headers
|
||||||
|
|
||||||
|
Headers are formatted as follows:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
POST /logs HTTP/1.1
|
||||||
|
Host: <DESTINATION_HOST>
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
X-Gitlab-Audit-Event-Type: project_group_link_create
|
||||||
|
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example payload for project group link create
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"author_id": 1,
|
||||||
|
"entity_id": 24,
|
||||||
|
"entity_type": "Project",
|
||||||
|
"details": {
|
||||||
|
"author_name": "example-user",
|
||||||
|
"target_id": 31,
|
||||||
|
"target_type": "Group",
|
||||||
|
"target_details": "another-group",
|
||||||
|
"custom_message": "Added project group link",
|
||||||
|
"ip_address": "127.0.0.1",
|
||||||
|
"entity_path": "example-group/example-project"
|
||||||
|
},
|
||||||
|
"ip_address": "127.0.0.1",
|
||||||
|
"author_name": "example-user",
|
||||||
|
"entity_path": "example-group/example-project",
|
||||||
|
"target_details": "another-group",
|
||||||
|
"created_at": "2022-07-04T00:43:09.318Z",
|
||||||
|
"target_type": "Group",
|
||||||
|
"target_id": 31,
|
||||||
|
"event_type": "project_group_link_create"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example payload for project group link update
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"author_id": 1,
|
||||||
|
"entity_id": 24,
|
||||||
|
"entity_type": "Project",
|
||||||
|
"details": {
|
||||||
|
"author_name": "example-user",
|
||||||
|
"target_id": 31,
|
||||||
|
"target_type": "Group",
|
||||||
|
"target_details": "another-group",
|
||||||
|
"custom_message": "Changed project group link profile group_access from Developer to Guest",
|
||||||
|
"ip_address": "127.0.0.1",
|
||||||
|
"entity_path": "example-group/example-project"
|
||||||
|
},
|
||||||
|
"ip_address": "127.0.0.1",
|
||||||
|
"author_name": "example-user",
|
||||||
|
"entity_path": "example-group/example-project",
|
||||||
|
"target_details": "another-group",
|
||||||
|
"created_at": "2022-07-04T00:43:28.328Z",
|
||||||
|
"target_type": "Group",
|
||||||
|
"target_id": 31,
|
||||||
|
"event_type": "project_group_link_update"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example payload for project group link delete
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"author_id": 1,
|
||||||
|
"entity_id": 24,
|
||||||
|
"entity_type": "Project",
|
||||||
|
"details": {
|
||||||
|
"author_name": "example-user",
|
||||||
|
"target_id": 31,
|
||||||
|
"target_type": "Group",
|
||||||
|
"target_details": "another-group",
|
||||||
|
"custom_message": "Removed project group link",
|
||||||
|
"ip_address": "127.0.0.1",
|
||||||
|
"entity_path": "example-group/example-project"
|
||||||
|
},
|
||||||
|
"ip_address": "127.0.0.1",
|
||||||
|
"author_name": "example-user",
|
||||||
|
"entity_path": "example-group/example-project",
|
||||||
|
"target_details": "another-group",
|
||||||
|
"created_at": "2022-07-04T00:42:56.279Z",
|
||||||
|
"target_type": "Group",
|
||||||
|
"target_id": 31,
|
||||||
|
"event_type": "project_group_link_destroy"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -24,7 +24,7 @@ GET /projects/:id/dora/metrics
|
||||||
| Attribute | Type | Required | Description |
|
| Attribute | Type | Required | Description |
|
||||||
|----------------------|------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------|------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
|
||||||
| `metric` | string | yes | The metric name: `deployment_frequency`, `lead_time_for_changes` or `time_to_restore_service`. |
|
| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
|
||||||
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
|
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
|
||||||
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
|
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
|
||||||
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
|
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
|
||||||
|
|
|
@ -15,16 +15,21 @@ To configure GitLab for this, see
|
||||||
|
|
||||||
This functionality is based on the [doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper).
|
This functionality is based on the [doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper).
|
||||||
|
|
||||||
## CORS preflight requests
|
## Cross-origin resource sharing
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/364680) in GitLab 15.1.
|
> CORS preflight request support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/364680) in GitLab 15.1.
|
||||||
|
|
||||||
The following endpoints support [CORS preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS):
|
Many `/oauth` endpoints support cross-origin resource sharing (CORS). From GitLab 15.1, the following endpoints also
|
||||||
|
support [CORS preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS):
|
||||||
|
|
||||||
- `/oauth/revoke`
|
- `/oauth/revoke`
|
||||||
- `/oauth/token`
|
- `/oauth/token`
|
||||||
- `/oauth/userinfo`
|
- `/oauth/userinfo`
|
||||||
|
|
||||||
|
In addition to the headers listed for [simple requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests),
|
||||||
|
only the `Authorization` header can be used for preflight requests. For example, the `X-Requested-With` header
|
||||||
|
can't be used for preflight requests.
|
||||||
|
|
||||||
## Supported OAuth 2.0 flows
|
## Supported OAuth 2.0 flows
|
||||||
|
|
||||||
GitLab supports the following authorization flows:
|
GitLab supports the following authorization flows:
|
||||||
|
|
|
@ -79,6 +79,7 @@ Example response:
|
||||||
"active_user_count": "SELECT COUNT(\"users\".\"id\") FROM \"users\" WHERE (\"users\".\"state\" IN ('active')) AND (\"users\".\"user_type\" IS NULL OR \"users\".\"user_type\" IN (NULL, 6, 4))",
|
"active_user_count": "SELECT COUNT(\"users\".\"id\") FROM \"users\" WHERE (\"users\".\"state\" IN ('active')) AND (\"users\".\"user_type\" IS NULL OR \"users\".\"user_type\" IN (NULL, 6, 4))",
|
||||||
"edition": "EE",
|
"edition": "EE",
|
||||||
"license_md5": "c701acc03844c45366dd175ef7a4e19c",
|
"license_md5": "c701acc03844c45366dd175ef7a4e19c",
|
||||||
|
"license_sha256": "366dd175ef7a4e19cc701acc03844c45366dd175ef7a4e19cc701acc03844c45",
|
||||||
"license_id": null,
|
"license_id": null,
|
||||||
"historical_max_users": 0,
|
"historical_max_users": 0,
|
||||||
"licensee": {
|
"licensee": {
|
||||||
|
@ -138,6 +139,7 @@ Sample response:
|
||||||
"active_user_count": -3,
|
"active_user_count": -3,
|
||||||
"edition": "EE",
|
"edition": "EE",
|
||||||
"license_md5": "bb8cd0d8a6d9569ff3f70b8927a1f949",
|
"license_md5": "bb8cd0d8a6d9569ff3f70b8927a1f949",
|
||||||
|
"license_sha256": "366dd175ef7a4e19cc701acc03844c45366dd175ef7a4e19cc701acc03844c45",
|
||||||
"license_id": null,
|
"license_id": null,
|
||||||
"historical_max_users": 0,
|
"historical_max_users": 0,
|
||||||
"licensee": {
|
"licensee": {
|
||||||
|
|
|
@ -200,6 +200,7 @@ The following is example content of the Service Ping payload.
|
||||||
"recorded_at": "2020-04-17T07:43:54.162+00:00",
|
"recorded_at": "2020-04-17T07:43:54.162+00:00",
|
||||||
"edition": "EEU",
|
"edition": "EEU",
|
||||||
"license_md5": "00000000000000000000000000000000",
|
"license_md5": "00000000000000000000000000000000",
|
||||||
|
"license_sha256: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
"license_id": null,
|
"license_id": null,
|
||||||
"historical_max_users": 999,
|
"historical_max_users": 999,
|
||||||
"licensee": {
|
"licensee": {
|
||||||
|
|
|
@ -159,7 +159,6 @@ The daily job provides **only** the following information to the Customers Porta
|
||||||
- GitLab version
|
- GitLab version
|
||||||
- Hostname
|
- Hostname
|
||||||
- Instance ID
|
- Instance ID
|
||||||
- MD5 hash of license
|
|
||||||
|
|
||||||
Example of a cloud licensing sync request:
|
Example of a cloud licensing sync request:
|
||||||
|
|
||||||
|
@ -208,8 +207,7 @@ Example of a cloud licensing sync request:
|
||||||
"max_historical_user_count": 75,
|
"max_historical_user_count": 75,
|
||||||
"billable_users_count": 75,
|
"billable_users_count": 75,
|
||||||
"hostname": "gitlab.example.com",
|
"hostname": "gitlab.example.com",
|
||||||
"instance_id": "9367590b-82ad-48cb-9da7-938134c29088",
|
"instance_id": "9367590b-82ad-48cb-9da7-938134c29088"
|
||||||
"license_md5": "002f02470fe45ef6a333a4282aca6222"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
|
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module BackgroundMigration
|
module BackgroundMigration
|
||||||
# Backfills the `issue_search_data` table for issues imported prior
|
# Rechedules the backfill for the `issue_search_data` table for issues imported prior
|
||||||
# to the fix for the imported issues search data bug:
|
# to the fix for the imported issues search data bug:
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/361219
|
|
||||||
class BackfillImportedIssueSearchData < BatchedMigrationJob
|
class BackfillImportedIssueSearchData < BatchedMigrationJob
|
||||||
|
SUB_BATCH_SIZE = 1_000
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
each_sub_batch(
|
each_sub_batch(
|
||||||
operation_name: :update_search_data,
|
operation_name: :update_search_data
|
||||||
batching_scope: -> (relation) { Issue }
|
|
||||||
) do |sub_batch|
|
) do |sub_batch|
|
||||||
update_search_data(sub_batch)
|
update_search_data(sub_batch)
|
||||||
rescue ActiveRecord::StatementInvalid => e
|
rescue ActiveRecord::StatementInvalid => e
|
||||||
|
@ -32,8 +33,7 @@ module Gitlab
|
||||||
NOW(),
|
NOW(),
|
||||||
NOW(),
|
NOW(),
|
||||||
setweight(to_tsvector('english', LEFT(title, 255)), 'A') || setweight(to_tsvector('english', LEFT(REGEXP_REPLACE(description, '[A-Za-z0-9+/@]{50,}', ' ', 'g'), 1048576)), 'B')
|
setweight(to_tsvector('english', LEFT(title, 255)), 'A') || setweight(to_tsvector('english', LEFT(REGEXP_REPLACE(description, '[A-Za-z0-9+/@]{50,}', ' ', 'g'), 1048576)), 'B')
|
||||||
FROM issues
|
FROM (#{relation.limit(SUB_BATCH_SIZE).to_sql}) issues
|
||||||
WHERE issues.id IN (#{relation.select(:id).to_sql})
|
|
||||||
ON CONFLICT DO NOTHING
|
ON CONFLICT DO NOTHING
|
||||||
SQL
|
SQL
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module BackgroundMigration
|
||||||
|
# Set `project_settings.legacy_open_source_license_available` to false for inactive, public projects
|
||||||
|
class DisableLegacyOpenSourceLicenseForInactivePublicProjects <
|
||||||
|
::Gitlab::BackgroundMigration::BatchedMigrationJob
|
||||||
|
PUBLIC = 20
|
||||||
|
LAST_ACTIVITY_DATE = '2021-07-01'
|
||||||
|
|
||||||
|
# Migration only version of `project_settings` table
|
||||||
|
class ProjectSetting < ApplicationRecord
|
||||||
|
self.table_name = 'project_settings'
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform
|
||||||
|
each_sub_batch(
|
||||||
|
operation_name: :disable_legacy_open_source_license_available,
|
||||||
|
batching_scope: ->(relation) {
|
||||||
|
relation.where(visibility_level: PUBLIC).where('last_activity_at < ?', LAST_ACTIVITY_DATE)
|
||||||
|
}
|
||||||
|
) do |sub_batch|
|
||||||
|
ProjectSetting.where(project_id: sub_batch).update_all(legacy_open_source_license_available: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,43 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module GithubImport
|
||||||
|
module Importer
|
||||||
|
module Events
|
||||||
|
class ChangedLabel
|
||||||
|
def initialize(project, user_id)
|
||||||
|
@project = project
|
||||||
|
@user_id = user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
# issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`.
|
||||||
|
def execute(issue_event)
|
||||||
|
create_event(issue_event)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :project, :user_id
|
||||||
|
|
||||||
|
def create_event(issue_event)
|
||||||
|
ResourceLabelEvent.create!(
|
||||||
|
issue_id: issue_event.issue_db_id,
|
||||||
|
user_id: user_id,
|
||||||
|
label_id: label_finder.id_for(issue_event.label_title),
|
||||||
|
action: action(issue_event.event),
|
||||||
|
created_at: issue_event.created_at
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def label_finder
|
||||||
|
Gitlab::GithubImport::LabelFinder.new(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def action(event_type)
|
||||||
|
event_type == 'unlabeled' ? 'remove' : 'add'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -24,6 +24,9 @@ module Gitlab
|
||||||
when 'reopened'
|
when 'reopened'
|
||||||
Gitlab::GithubImport::Importer::Events::Reopened.new(project, author_id)
|
Gitlab::GithubImport::Importer::Events::Reopened.new(project, author_id)
|
||||||
.execute(issue_event)
|
.execute(issue_event)
|
||||||
|
when 'labeled', 'unlabeled'
|
||||||
|
Gitlab::GithubImport::Importer::Events::ChangedLabel.new(project, author_id)
|
||||||
|
.execute(issue_event)
|
||||||
else
|
else
|
||||||
Gitlab::GithubImport::Logger.debug(
|
Gitlab::GithubImport::Logger.debug(
|
||||||
message: 'UNSUPPORTED_EVENT_TYPE',
|
message: 'UNSUPPORTED_EVENT_TYPE',
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Gitlab
|
||||||
|
|
||||||
attr_reader :attributes
|
attr_reader :attributes
|
||||||
|
|
||||||
expose_attribute :id, :actor, :event, :commit_id, :created_at
|
expose_attribute :id, :actor, :event, :commit_id, :label_title, :created_at
|
||||||
expose_attribute :issue_db_id # set in SingleEndpointIssueEventsImporter#each_associated
|
expose_attribute :issue_db_id # set in SingleEndpointIssueEventsImporter#each_associated
|
||||||
|
|
||||||
# Builds a event from a GitHub API response.
|
# Builds a event from a GitHub API response.
|
||||||
|
@ -21,6 +21,7 @@ module Gitlab
|
||||||
actor: event.actor && Representation::User.from_api_response(event.actor),
|
actor: event.actor && Representation::User.from_api_response(event.actor),
|
||||||
event: event.event,
|
event: event.event,
|
||||||
commit_id: event.commit_id,
|
commit_id: event.commit_id,
|
||||||
|
label_title: event.label && event.label[:name],
|
||||||
issue_db_id: event.issue_db_id,
|
issue_db_id: event.issue_db_id,
|
||||||
created_at: event.created_at
|
created_at: event.created_at
|
||||||
)
|
)
|
||||||
|
|
|
@ -149,6 +149,19 @@ module Gitlab
|
||||||
|
|
||||||
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(action, values: author.id)
|
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(action, values: author.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def track_snowplow_action(action, author, project)
|
||||||
|
return unless Feature.enabled?(:route_hll_to_snowplow_phase2, project&.namespace)
|
||||||
|
return unless author
|
||||||
|
|
||||||
|
Gitlab::Tracking.event(
|
||||||
|
ISSUE_CATEGORY,
|
||||||
|
action.to_s,
|
||||||
|
project: project,
|
||||||
|
namespace: project&.namespace,
|
||||||
|
user: author
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14860,6 +14860,9 @@ msgstr ""
|
||||||
msgid "Epics|Something went wrong while updating epics."
|
msgid "Epics|Something went wrong while updating epics."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Epics|The color for the epic when it's visualized, such as on roadmap timeline bars."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Epics|This epic and any containing child epics are confidential and should only be visible to team members with at least Reporter access."
|
msgid "Epics|This epic and any containing child epics are confidential and should only be visible to team members with at least Reporter access."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Create' do
|
RSpec.describe 'Create', quarantine: {
|
||||||
|
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/352525',
|
||||||
|
type: :test_environment,
|
||||||
|
only: { job: 'review-qa-*' }
|
||||||
|
} do
|
||||||
describe 'Push mirror a repository over HTTP' do
|
describe 'Push mirror a repository over HTTP' do
|
||||||
it 'configures and syncs LFS objects for a (push) mirrored repository', :aggregate_failures, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347847' do
|
it 'configures and syncs LFS objects for a (push) mirrored repository', :aggregate_failures, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347847' do
|
||||||
Runtime::Browser.visit(:gitlab, Page::Main::Login)
|
Runtime::Browser.visit(:gitlab, Page::Main::Login)
|
||||||
|
|
|
@ -35,7 +35,7 @@ describe('User List Edit Mutations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(types.RECIEVE_USER_LIST_ERROR, () => {
|
describe(types.RECEIVE_USER_LIST_ERROR, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mutations[types.RECEIVE_USER_LIST_ERROR](state, ['network error']);
|
mutations[types.RECEIVE_USER_LIST_ERROR](state, ['network error']);
|
||||||
});
|
});
|
||||||
|
@ -44,7 +44,7 @@ describe('User List Edit Mutations', () => {
|
||||||
expect(state.status).toBe(statuses.ERROR);
|
expect(state.status).toBe(statuses.ERROR);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets the error message to the recieved one', () => {
|
it('sets the error message to the received one', () => {
|
||||||
expect(state.errorMessage).toEqual(['network error']);
|
expect(state.errorMessage).toEqual(['network error']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@ describe('User List Edit Mutations', () => {
|
||||||
state = createState({ projectId: '1' });
|
state = createState({ projectId: '1' });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(types.RECIEVE_USER_LIST_ERROR, () => {
|
describe(types.RECEIVE_USER_LIST_ERROR, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mutations[types.RECEIVE_CREATE_USER_LIST_ERROR](state, ['network error']);
|
mutations[types.RECEIVE_CREATE_USER_LIST_ERROR](state, ['network error']);
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require_migration!
|
require_migration!
|
||||||
|
|
||||||
RSpec.describe Gitlab::BackgroundMigration::BackfillImportedIssueSearchData, :migration, schema: 20220621040800 do
|
RSpec.describe Gitlab::BackgroundMigration::BackfillImportedIssueSearchData,
|
||||||
|
:migration,
|
||||||
|
schema: 20220707075300 do
|
||||||
let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
|
let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
|
||||||
let!(:issue_search_data_table) { table(:issue_search_data) }
|
let!(:issue_search_data_table) { table(:issue_search_data) }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForInactivePublicProjects, :migration do
|
||||||
|
let(:namespaces_table) { table(:namespaces) }
|
||||||
|
let(:projects_table) { table(:projects) }
|
||||||
|
let(:project_settings_table) { table(:project_settings) }
|
||||||
|
|
||||||
|
subject(:perform_migration) do
|
||||||
|
described_class.new(start_id: projects_table.minimum(:id),
|
||||||
|
end_id: projects_table.maximum(:id),
|
||||||
|
batch_table: :projects,
|
||||||
|
batch_column: :id,
|
||||||
|
sub_batch_size: 2,
|
||||||
|
pause_ms: 0,
|
||||||
|
connection: ActiveRecord::Base.connection)
|
||||||
|
.perform
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:queries) { ActiveRecord::QueryRecorder.new { perform_migration } }
|
||||||
|
|
||||||
|
let(:namespace_1) { namespaces_table.create!(name: 'namespace', path: 'namespace-path-1') }
|
||||||
|
let(:project_namespace_2) { namespaces_table.create!(name: 'namespace', path: 'namespace-path-2', type: 'Project') }
|
||||||
|
let(:project_namespace_3) { namespaces_table.create!(name: 'namespace', path: 'namespace-path-3', type: 'Project') }
|
||||||
|
let(:project_namespace_4) { namespaces_table.create!(name: 'namespace', path: 'namespace-path-4', type: 'Project') }
|
||||||
|
let(:project_namespace_5) { namespaces_table.create!(name: 'namespace', path: 'namespace-path-5', type: 'Project') }
|
||||||
|
|
||||||
|
let(:project_1) do
|
||||||
|
projects_table
|
||||||
|
.create!(
|
||||||
|
name: 'proj-1', path: 'path-1', namespace_id: namespace_1.id,
|
||||||
|
project_namespace_id: project_namespace_2.id, visibility_level: 0
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:project_2) do
|
||||||
|
projects_table
|
||||||
|
.create!(
|
||||||
|
name: 'proj-2', path: 'path-2', namespace_id: namespace_1.id,
|
||||||
|
project_namespace_id: project_namespace_3.id, visibility_level: 10
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:project_3) do
|
||||||
|
projects_table
|
||||||
|
.create!(
|
||||||
|
name: 'proj-3', path: 'path-3', namespace_id: namespace_1.id,
|
||||||
|
project_namespace_id: project_namespace_4.id, visibility_level: 20, last_activity_at: '2021-01-01'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:project_4) do
|
||||||
|
projects_table
|
||||||
|
.create!(
|
||||||
|
name: 'proj-4', path: 'path-4', namespace_id: namespace_1.id,
|
||||||
|
project_namespace_id: project_namespace_5.id, visibility_level: 20, last_activity_at: '2022-01-01'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
project_settings_table.create!(project_id: project_1.id, legacy_open_source_license_available: true)
|
||||||
|
project_settings_table.create!(project_id: project_2.id, legacy_open_source_license_available: true)
|
||||||
|
project_settings_table.create!(project_id: project_3.id, legacy_open_source_license_available: true)
|
||||||
|
project_settings_table.create!(project_id: project_4.id, legacy_open_source_license_available: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets `legacy_open_source_license_available` attribute to false for inactive, public projects',
|
||||||
|
:aggregate_failures do
|
||||||
|
expect(queries.count).to eq(5)
|
||||||
|
|
||||||
|
expect(migrated_attribute(project_1.id)).to be_truthy
|
||||||
|
expect(migrated_attribute(project_2.id)).to be_truthy
|
||||||
|
expect(migrated_attribute(project_3.id)).to be_falsey
|
||||||
|
expect(migrated_attribute(project_4.id)).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
def migrated_attribute(project_id)
|
||||||
|
project_settings_table.find(project_id).legacy_open_source_license_available
|
||||||
|
end
|
||||||
|
end
|
|
@ -188,7 +188,7 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'a failed branch deletion' do
|
shared_examples 'a failed branch deletion' do
|
||||||
it 'raises a PreRecieveError' do
|
it 'raises a PreReceiveError' do
|
||||||
expect_any_instance_of(Gitaly::OperationService::Stub)
|
expect_any_instance_of(Gitaly::OperationService::Stub)
|
||||||
.to receive(:user_delete_branch).with(request, kind_of(Hash))
|
.to receive(:user_delete_branch).with(request, kind_of(Hash))
|
||||||
.and_raise(custom_hook_error)
|
.and_raise(custom_hook_error)
|
||||||
|
@ -288,7 +288,7 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'a failed merge' do
|
shared_examples 'a failed merge' do
|
||||||
it 'raises a PreRecieveError' do
|
it 'raises a PreReceiveError' do
|
||||||
expect_any_instance_of(Gitaly::OperationService::Stub)
|
expect_any_instance_of(Gitaly::OperationService::Stub)
|
||||||
.to receive(:user_merge_branch).with(kind_of(Enumerator), kind_of(Hash))
|
.to receive(:user_merge_branch).with(kind_of(Enumerator), kind_of(Hash))
|
||||||
.and_raise(custom_hook_error)
|
.and_raise(custom_hook_error)
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe Gitlab::GithubImport::Importer::Events::ChangedLabel do
|
||||||
|
subject(:importer) { described_class.new(project, user.id) }
|
||||||
|
|
||||||
|
let_it_be(:project) { create(:project, :repository) }
|
||||||
|
let_it_be(:user) { create(:user) }
|
||||||
|
|
||||||
|
let(:issue) { create(:issue, project: project) }
|
||||||
|
let!(:label) { create(:label, project: project) }
|
||||||
|
|
||||||
|
let(:issue_event) do
|
||||||
|
Gitlab::GithubImport::Representation::IssueEvent.from_json_hash(
|
||||||
|
'id' => 6501124486,
|
||||||
|
'actor' => { 'id' => 4, 'login' => 'alice' },
|
||||||
|
'event' => event_type,
|
||||||
|
'commit_id' => nil,
|
||||||
|
'label_title' => label.title,
|
||||||
|
'issue_db_id' => issue.id,
|
||||||
|
'created_at' => '2022-04-26 18:30:53 UTC'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:event_attrs) do
|
||||||
|
{
|
||||||
|
user_id: user.id,
|
||||||
|
issue_id: issue.id,
|
||||||
|
label_id: label.id,
|
||||||
|
created_at: issue_event.created_at
|
||||||
|
}.stringify_keys
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples 'new event' do
|
||||||
|
it 'creates a new label event' do
|
||||||
|
expect { importer.execute(issue_event) }.to change { issue.resource_label_events.count }
|
||||||
|
.from(0).to(1)
|
||||||
|
expect(issue.resource_label_events.last)
|
||||||
|
.to have_attributes(expected_event_attrs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Gitlab::Cache::Import::Caching).to receive(:read_integer).and_return(label.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when importing a labeled event' do
|
||||||
|
let(:event_type) { 'labeled' }
|
||||||
|
let(:expected_event_attrs) { event_attrs.merge(action: 'add') }
|
||||||
|
|
||||||
|
it_behaves_like 'new event'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when importing an unlabeled event' do
|
||||||
|
let(:event_type) { 'unlabeled' }
|
||||||
|
let(:expected_event_attrs) { event_attrs.merge(action: 'remove') }
|
||||||
|
|
||||||
|
it_behaves_like 'new event'
|
||||||
|
end
|
||||||
|
end
|
|
@ -66,6 +66,20 @@ RSpec.describe Gitlab::GithubImport::Importer::IssueEventImporter, :clean_gitlab
|
||||||
Gitlab::GithubImport::Importer::Events::Reopened
|
Gitlab::GithubImport::Importer::Events::Reopened
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when it's labeled issue event" do
|
||||||
|
let(:event_name) { 'labeled' }
|
||||||
|
|
||||||
|
it_behaves_like 'triggers specific event importer',
|
||||||
|
Gitlab::GithubImport::Importer::Events::ChangedLabel
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when it's unlabeled issue event" do
|
||||||
|
let(:event_name) { 'unlabeled' }
|
||||||
|
|
||||||
|
it_behaves_like 'triggers specific event importer',
|
||||||
|
Gitlab::GithubImport::Importer::Events::ChangedLabel
|
||||||
|
end
|
||||||
|
|
||||||
context "when it's unknown issue event" do
|
context "when it's unknown issue event" do
|
||||||
let(:event_name) { 'fake' }
|
let(:event_name) { 'fake' }
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,20 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when label data is present' do
|
||||||
|
it 'includes the label_title' do
|
||||||
|
expect(issue_event.label_title).to eq('label title')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when label data is empty' do
|
||||||
|
let(:with_label) { false }
|
||||||
|
|
||||||
|
it 'does not return such info' do
|
||||||
|
expect(issue_event.label_title).to eq nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it 'includes the created timestamp' do
|
it 'includes the created timestamp' do
|
||||||
expect(issue_event.created_at).to eq('2022-04-26 18:30:53 UTC')
|
expect(issue_event.created_at).to eq('2022-04-26 18:30:53 UTC')
|
||||||
end
|
end
|
||||||
|
@ -58,7 +72,7 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
|
||||||
describe '.from_api_response' do
|
describe '.from_api_response' do
|
||||||
let(:response) do
|
let(:response) do
|
||||||
event_resource = Struct.new(
|
event_resource = Struct.new(
|
||||||
:id, :node_id, :url, :actor, :event, :commit_id, :commit_url,
|
:id, :node_id, :url, :actor, :event, :commit_id, :commit_url, :label,
|
||||||
:issue_db_id, :created_at, :performed_via_github_app,
|
:issue_db_id, :created_at, :performed_via_github_app,
|
||||||
keyword_init: true
|
keyword_init: true
|
||||||
)
|
)
|
||||||
|
@ -73,12 +87,14 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
|
||||||
commit_url: 'https://api.github.com/repos/octocat/Hello-World/commits'\
|
commit_url: 'https://api.github.com/repos/octocat/Hello-World/commits'\
|
||||||
'/570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
|
'/570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
|
||||||
issue_db_id: 100500,
|
issue_db_id: 100500,
|
||||||
|
label: with_label ? { name: 'label title' } : nil,
|
||||||
created_at: '2022-04-26 18:30:53 UTC',
|
created_at: '2022-04-26 18:30:53 UTC',
|
||||||
performed_via_github_app: nil
|
performed_via_github_app: nil
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:with_actor) { true }
|
let(:with_actor) { true }
|
||||||
|
let(:with_label) { true }
|
||||||
|
|
||||||
it_behaves_like 'an IssueEvent' do
|
it_behaves_like 'an IssueEvent' do
|
||||||
let(:issue_event) { described_class.from_api_response(response) }
|
let(:issue_event) { described_class.from_api_response(response) }
|
||||||
|
@ -97,6 +113,7 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
|
||||||
'commit_id' => '570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
|
'commit_id' => '570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
|
||||||
'commit_url' =>
|
'commit_url' =>
|
||||||
'https://api.github.com/repos/octocat/Hello-World/commits/570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
|
'https://api.github.com/repos/octocat/Hello-World/commits/570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
|
||||||
|
'label_title' => (with_label ? 'label title' : nil),
|
||||||
"issue_db_id" => 100500,
|
"issue_db_id" => 100500,
|
||||||
'created_at' => '2022-04-26 18:30:53 UTC',
|
'created_at' => '2022-04-26 18:30:53 UTC',
|
||||||
'performed_via_github_app' => nil
|
'performed_via_github_app' => nil
|
||||||
|
@ -104,6 +121,7 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:with_actor) { true }
|
let(:with_actor) { true }
|
||||||
|
let(:with_label) { true }
|
||||||
|
|
||||||
let(:issue_event) { described_class.from_json_hash(hash) }
|
let(:issue_event) { described_class.from_json_hash(hash) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
require_migration!
|
||||||
|
|
||||||
|
RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForInactivePublicProjects do
|
||||||
|
context 'on gitlab.com' do
|
||||||
|
let(:migration) { described_class::MIGRATION }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Gitlab).to receive(:com?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#up' do
|
||||||
|
it 'schedules background jobs for each batch of projects' do
|
||||||
|
migrate!
|
||||||
|
|
||||||
|
expect(migration).to(
|
||||||
|
have_scheduled_batched_migration(
|
||||||
|
table_name: :projects,
|
||||||
|
column_name: :id,
|
||||||
|
interval: described_class::INTERVAL,
|
||||||
|
batch_size: described_class::BATCH_SIZE,
|
||||||
|
sub_batch_size: described_class::SUB_BATCH_SIZE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#down' do
|
||||||
|
it 'deletes all batched migration records' do
|
||||||
|
migrate!
|
||||||
|
schema_migrate_down!
|
||||||
|
|
||||||
|
expect(migration).not_to have_scheduled_batched_migration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on self-managed instances' do
|
||||||
|
let(:migration) { described_class.new }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Gitlab).to receive(:com?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#up' do
|
||||||
|
it 'does not schedule background job' do
|
||||||
|
expect(migration).not_to receive(:queue_batched_background_migration)
|
||||||
|
|
||||||
|
migration.up
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#down' do
|
||||||
|
it 'does not delete background job' do
|
||||||
|
expect(migration).not_to receive(:delete_batched_background_migration)
|
||||||
|
|
||||||
|
migration.down
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,18 +3,17 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require_migration!
|
require_migration!
|
||||||
|
|
||||||
RSpec.describe BackfillImportedIssueSearchData do
|
RSpec.describe RescheduleBackfillImportedIssueSearchData do
|
||||||
let_it_be(:batched_migration) { described_class::MIGRATION }
|
let_it_be(:reschedule_migration) { described_class::MIGRATION }
|
||||||
|
|
||||||
context 'when BackfillIssueSearchData.max_value is nil' do
|
context 'when BackfillIssueSearchData.max_value is nil' do
|
||||||
it 'schedules a new batched migration with a default max_value' do
|
it 'schedules a new batched migration with a default value' do
|
||||||
reversible_migration do |migration|
|
reversible_migration do |migration|
|
||||||
migration.before -> {
|
migration.before -> {
|
||||||
expect(batched_migration).not_to have_scheduled_batched_migration
|
expect(reschedule_migration).not_to have_scheduled_batched_migration
|
||||||
}
|
}
|
||||||
|
|
||||||
migration.after -> {
|
migration.after -> {
|
||||||
expect(batched_migration).to have_scheduled_batched_migration(
|
expect(reschedule_migration).to have_scheduled_batched_migration(
|
||||||
table_name: :issues,
|
table_name: :issues,
|
||||||
column_name: :id,
|
column_name: :id,
|
||||||
interval: described_class::DELAY_INTERVAL,
|
interval: described_class::DELAY_INTERVAL,
|
||||||
|
@ -43,7 +42,7 @@ RSpec.describe BackfillImportedIssueSearchData do
|
||||||
it 'schedules a new batched migration with a custom max_value' do
|
it 'schedules a new batched migration with a custom max_value' do
|
||||||
reversible_migration do |migration|
|
reversible_migration do |migration|
|
||||||
migration.after -> {
|
migration.after -> {
|
||||||
expect(batched_migration).to have_scheduled_batched_migration(
|
expect(reschedule_migration).to have_scheduled_batched_migration(
|
||||||
table_name: :issues,
|
table_name: :issues,
|
||||||
column_name: :id,
|
column_name: :id,
|
||||||
interval: described_class::DELAY_INTERVAL,
|
interval: described_class::DELAY_INTERVAL,
|
|
@ -1479,7 +1479,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
||||||
let(:build_c) { create_build('build3', queued_at: 0) }
|
let(:build_c) { create_build('build3', queued_at: 0) }
|
||||||
|
|
||||||
%w[succeed! drop! cancel! skip! block! delay!].each do |action|
|
%w[succeed! drop! cancel! skip! block! delay!].each do |action|
|
||||||
context "when the pipeline recieved #{action} event" do
|
context "when the pipeline received #{action} event" do
|
||||||
it 'deletes a persistent ref' do
|
it 'deletes a persistent ref' do
|
||||||
expect(pipeline.persistent_ref).to receive(:delete).once
|
expect(pipeline.persistent_ref).to receive(:delete).once
|
||||||
|
|
||||||
|
@ -1702,7 +1702,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
||||||
end
|
end
|
||||||
|
|
||||||
%w[succeed! drop! cancel! skip!].each do |action|
|
%w[succeed! drop! cancel! skip!].each do |action|
|
||||||
context "when the pipeline recieved #{action} event" do
|
context "when the pipeline received #{action} event" do
|
||||||
it 'performs AutoMergeProcessWorker' do
|
it 'performs AutoMergeProcessWorker' do
|
||||||
expect(AutoMergeProcessWorker).to receive(:perform_async).with(merge_request.id)
|
expect(AutoMergeProcessWorker).to receive(:perform_async).with(merge_request.id)
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ RSpec.describe Projects::GroupLinks::UpdateService, '#execute' do
|
||||||
expires_at: expiry_date }
|
expires_at: expiry_date }
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { described_class.new(link).execute(group_link_params) }
|
subject { described_class.new(link, user).execute(group_link_params) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
group.add_developer(user)
|
group.add_developer(user)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#
|
#
|
||||||
# Requires a context containing:
|
# Requires a context containing:
|
||||||
# - subject
|
# - subject
|
||||||
|
# - project
|
||||||
# - feature_flag_name
|
# - feature_flag_name
|
||||||
# - category
|
# - category
|
||||||
# - action
|
# - action
|
||||||
|
|
|
@ -32,3 +32,45 @@ RSpec.shared_examples 'does not track when feature flag is disabled' do |feature
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RSpec.shared_examples 'a daily tracked issuable snowplow and service ping events' do
|
||||||
|
before do
|
||||||
|
stub_application_setting(usage_ping_enabled: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_unique(date_from: 1.minute.ago, date_to: 1.minute.from_now)
|
||||||
|
Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: action, start_date: date_from, end_date: date_to)
|
||||||
|
end
|
||||||
|
|
||||||
|
specify do
|
||||||
|
aggregate_failures do
|
||||||
|
expect(track_action(author: user1, project: project)).to be_truthy
|
||||||
|
expect(track_action(author: user1, project: project)).to be_truthy
|
||||||
|
expect(track_action(author: user2, project: project)).to be_truthy
|
||||||
|
expect(count_unique).to eq(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not track edit actions if author is not present' do
|
||||||
|
expect(track_action(author: nil, project: project)).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'emits snowplow event' do
|
||||||
|
track_action(author: user1, project: project)
|
||||||
|
|
||||||
|
expect_snowplow_event(category: 'issues_edit', action: action, user: user1,
|
||||||
|
namespace: project.namespace, project: project)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with route_hll_to_snowplow_phase2 disabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(route_hll_to_snowplow_phase2: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not emit snowplow event' do
|
||||||
|
track_action(author: user1, project: project)
|
||||||
|
|
||||||
|
expect_no_snowplow_event
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -274,6 +274,32 @@ RSpec.describe PostReceive do
|
||||||
|
|
||||||
expect { perform }.to change { counter.read(:pushes) }.by(1)
|
expect { perform }.to change { counter.read(:pushes) }.by(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'records correct payload with Snowplow event', :snowplow do
|
||||||
|
stub_feature_flags(route_hll_to_snowplow_phase2: true)
|
||||||
|
|
||||||
|
perform
|
||||||
|
|
||||||
|
expect_snowplow_event(
|
||||||
|
category: 'PostReceive',
|
||||||
|
action: 'source_code_pushes',
|
||||||
|
namespace: project.namespace,
|
||||||
|
user: project.first_owner,
|
||||||
|
project: project
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when FF is disabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(route_hll_to_snowplow_phase2: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesnt emit snowplow events', :snowplow do
|
||||||
|
perform
|
||||||
|
|
||||||
|
expect_no_snowplow_event
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ func handleLimitErr(err error, w io.Writer, f func(w io.Writer) error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeReceivePackError writes a "server is busy" error message to the
|
// writeReceivePackError writes a "server is busy" error message to the
|
||||||
// git-recieve-pack-result.
|
// git-receive-pack-result.
|
||||||
//
|
//
|
||||||
// 0023\x01001aunpack server is busy
|
// 0023\x01001aunpack server is busy
|
||||||
// 00000044\x2GitLab is currently unable to handle this request due to load.
|
// 00000044\x2GitLab is currently unable to handle this request due to load.
|
||||||
|
|
|
@ -30,7 +30,7 @@ func TestHandleLimitErr(t *testing.T) {
|
||||||
}, []byte{}),
|
}, []byte{}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "recieve pack",
|
desc: "receive pack",
|
||||||
errWriter: writeReceivePackError,
|
errWriter: writeReceivePackError,
|
||||||
expectedBytes: bytes.Join([][]byte{
|
expectedBytes: bytes.Join([][]byte{
|
||||||
{'0', '0', '2', '3', 1, '0', '0', '1', 'a'},
|
{'0', '0', '2', '3', 1, '0', '0', '1', 'a'},
|
||||||
|
|
Loading…
Reference in New Issue