Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f3bcf3c911
commit
023c409645
20 changed files with 352 additions and 185 deletions
|
@ -29,7 +29,7 @@ run-dev-fixtures-ee:
|
|||
extends:
|
||||
- .run-dev-fixtures
|
||||
- .dev-fixtures:rules:ee-only
|
||||
- .use-pg12-ee
|
||||
- .use-pg12-es7-ee
|
||||
script:
|
||||
- cp ee/db/fixtures/development/* $FIXTURE_PATH
|
||||
- *run-dev-fixtures-script
|
||||
|
|
|
@ -275,34 +275,34 @@
|
|||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
PG_VERSION: "13"
|
||||
|
||||
.use-pg11-ee:
|
||||
.use-pg11-es7-ee:
|
||||
services:
|
||||
- name: postgres:11.6
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:5.0-alpine
|
||||
- name: elasticsearch:7.17.0
|
||||
- name: elasticsearch:7.17.6
|
||||
command: ["elasticsearch", "-E", "discovery.type=single-node", "-E", "xpack.security.enabled=false"]
|
||||
variables:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
PG_VERSION: "11"
|
||||
|
||||
.use-pg12-ee:
|
||||
.use-pg12-es7-ee:
|
||||
services:
|
||||
- name: postgres:12
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:6.0-alpine
|
||||
- name: elasticsearch:7.17.0
|
||||
- name: elasticsearch:7.17.6
|
||||
command: ["elasticsearch", "-E", "discovery.type=single-node", "-E", "xpack.security.enabled=false"]
|
||||
variables:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
PG_VERSION: "12"
|
||||
|
||||
.use-pg13-ee:
|
||||
.use-pg13-es7-ee:
|
||||
services:
|
||||
- name: postgres:13
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:6.2-alpine
|
||||
- name: elasticsearch:7.17.0
|
||||
- name: elasticsearch:7.17.6
|
||||
command: ["elasticsearch", "-E", "discovery.type=single-node", "-E", "xpack.security.enabled=false"]
|
||||
variables:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
|
@ -313,7 +313,7 @@
|
|||
- name: postgres:12
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:6.0-alpine
|
||||
- name: elasticsearch:8.3.3
|
||||
- name: elasticsearch:8.4.1
|
||||
variables:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
PG_VERSION: "12"
|
||||
|
@ -325,7 +325,19 @@
|
|||
- name: postgres:12
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:6.0-alpine
|
||||
- name: opensearchproject/opensearch:1.2.4
|
||||
- name: opensearchproject/opensearch:1.3.5
|
||||
alias: elasticsearch
|
||||
command: ["bin/opensearch", "-E", "discovery.type=single-node", "-E", "plugins.security.disabled=true"]
|
||||
variables:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
PG_VERSION: "12"
|
||||
|
||||
.use-pg12-opensearch2-ee:
|
||||
services:
|
||||
- name: postgres:12
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
- name: redis:6.0-alpine
|
||||
- name: opensearchproject/opensearch:2.2.1
|
||||
alias: elasticsearch
|
||||
command: ["bin/opensearch", "-E", "discovery.type=single-node", "-E", "plugins.security.disabled=true"]
|
||||
variables:
|
||||
|
|
|
@ -574,11 +574,6 @@ rspec-ee unit pg12 es8:
|
|||
- .rspec-ee-base-pg12-es8
|
||||
- .rspec-ee-unit-parallel
|
||||
|
||||
rspec-ee unit pg12 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch1
|
||||
- .rspec-ee-unit-parallel
|
||||
|
||||
rspec-ee unit pg12 minimal:
|
||||
extends:
|
||||
- rspec-ee unit pg12
|
||||
|
@ -602,11 +597,6 @@ rspec-ee integration pg12 es8:
|
|||
- .rspec-ee-base-pg12-es8
|
||||
- .rspec-ee-integration-parallel
|
||||
|
||||
rspec-ee integration pg12 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch1
|
||||
- .rspec-ee-integration-parallel
|
||||
|
||||
rspec-ee integration pg12 minimal:
|
||||
extends:
|
||||
- rspec-ee integration pg12
|
||||
|
@ -630,11 +620,6 @@ rspec-ee system pg12 es8:
|
|||
- .rspec-ee-base-pg12-es8
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
rspec-ee system pg12 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch1
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
rspec-ee system pg12 minimal:
|
||||
extends:
|
||||
- rspec-ee system pg12
|
||||
|
@ -743,6 +728,61 @@ rspec-ee system pg11:
|
|||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
# PG12
|
||||
rspec-ee unit pg12 es7:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-es7
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee unit pg12 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch1
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee unit pg12 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch2
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg12 es7:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-es7
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg12 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch1
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg12 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch2
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg12 es7:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-es7
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg12 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch1
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg12 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12-opensearch2
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# PG13
|
||||
rspec-ee migration pg13:
|
||||
extends:
|
||||
|
|
|
@ -109,12 +109,18 @@ include:
|
|||
.rspec-ee-base-pg11:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg11-ee
|
||||
- .use-pg11-es7-ee
|
||||
|
||||
.rspec-ee-base-pg12:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg12-ee
|
||||
- .use-pg12-es7-ee
|
||||
|
||||
.rspec-ee-base-pg12-es7:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg12-es7-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg12-es8:
|
||||
extends:
|
||||
|
@ -128,10 +134,16 @@ include:
|
|||
- .use-pg12-opensearch1-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg12-opensearch2:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg12-opensearch2-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg13:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg13-ee
|
||||
- .use-pg13-es7-ee
|
||||
|
||||
.db-job-base:
|
||||
extends:
|
||||
|
|
|
@ -573,6 +573,8 @@
|
|||
rules:
|
||||
- <<: *if-merge-request-labels-group-global-search
|
||||
changes: *search-backend-patterns
|
||||
- <<: *if-merge-request-labels-group-global-search
|
||||
changes: *ci-patterns
|
||||
|
||||
.rails:rules:ee-and-foss-default-rules:
|
||||
rules:
|
||||
|
|
|
@ -145,7 +145,8 @@ export default {
|
|||
},
|
||||
currentTabIndex: {
|
||||
get() {
|
||||
return this.$options.tabsConfig.findIndex((tab) => tab.id === this.activeTab);
|
||||
const tabIndex = this.$options.tabsConfig.findIndex((tab) => tab.id === this.activeTab);
|
||||
return tabIndex >= 0 ? tabIndex : 0;
|
||||
},
|
||||
set(tabIdx) {
|
||||
const tabId = this.$options.tabsConfig[tabIdx].id;
|
||||
|
|
|
@ -5,9 +5,26 @@ import { joinPaths } from '~/lib/utils/url_utility';
|
|||
Vue.use(VueRouter);
|
||||
|
||||
export default function createRouter(base) {
|
||||
return new VueRouter({
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: joinPaths(gon.relative_url_root || '', base),
|
||||
routes: [{ path: '/:tabId', name: 'tab' }],
|
||||
});
|
||||
|
||||
/*
|
||||
Backward-compatible behavior. Redirects hash mode URLs to history mode ones.
|
||||
Ex: from #/overview to /overview
|
||||
from #/metrics to /metrics
|
||||
from #/activity to /activity
|
||||
*/
|
||||
router.beforeEach((to, _, next) => {
|
||||
if (to.hash.startsWith('#/')) {
|
||||
const path = to.fullPath.substring(2);
|
||||
next(path);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
|
|
|
@ -38,128 +38,6 @@ This content has been converted to a Rake task, see [verify database values can
|
|||
|
||||
This content has been moved to [Troubleshooting Repository mirroring](../../user/project/repository/mirror/index.md#transfer-mirror-users-and-tokens-to-a-single-service-account-in-rails-console).
|
||||
|
||||
## Users
|
||||
|
||||
### Create new user
|
||||
|
||||
```ruby
|
||||
u = User.new(username: 'test_user', email: 'test@example.com', name: 'Test User', password: 'password', password_confirmation: 'password')
|
||||
u.skip_confirmation! # Use it only if you wish user to be automatically confirmed. If skipped, user receives confirmation e-mail
|
||||
u.save!
|
||||
```
|
||||
|
||||
### Skip reconfirmation
|
||||
|
||||
```ruby
|
||||
user = User.find_by_username('<username>')
|
||||
user.skip_reconfirmation!
|
||||
```
|
||||
|
||||
### Disable 2fa for single user
|
||||
|
||||
**In GitLab 13.5 and later:**
|
||||
|
||||
Use the code under [Disable 2FA | For a single user](../../security/two_factor_authentication.md#for-a-single-user) so that the target user
|
||||
is notified that 2FA has been disabled.
|
||||
|
||||
**In GitLab 13.4 and earlier:**
|
||||
|
||||
```ruby
|
||||
user = User.find_by_username('<username>')
|
||||
user.disable_two_factor!
|
||||
```
|
||||
|
||||
### Active users & Historical users
|
||||
|
||||
```ruby
|
||||
# Active users on the instance, now
|
||||
User.active.count
|
||||
|
||||
# Users taking a seat on the instance
|
||||
User.billable.count
|
||||
|
||||
# The historical max on the instance as of the past year
|
||||
::HistoricalData.max_historical_user_count(from: 1.year.ago.beginning_of_day, to: Time.current.end_of_day)
|
||||
```
|
||||
|
||||
Using cURL and jq (up to a max 100, see [Pagination](../../api/index.md#pagination)):
|
||||
|
||||
```shell
|
||||
curl --silent --header "Private-Token: ********************" \
|
||||
"https://gitlab.example.com/api/v4/users?per_page=100&active" | jq --compact-output '.[] | [.id,.name,.username]'
|
||||
```
|
||||
|
||||
### Update Daily Billable & Historical users
|
||||
|
||||
```ruby
|
||||
# Forces recount of historical (max) users
|
||||
::HistoricalDataWorker.new.perform
|
||||
|
||||
# Forces recount of daily billable users
|
||||
identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users]
|
||||
::Analytics::UsageTrends::CounterJobWorker.new.perform(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now)
|
||||
```
|
||||
|
||||
### Block or Delete Users that have no projects or groups
|
||||
|
||||
```ruby
|
||||
users = User.where('id NOT IN (select distinct(user_id) from project_authorizations)')
|
||||
|
||||
# How many users are removed?
|
||||
users.count
|
||||
|
||||
# If that count looks sane:
|
||||
|
||||
# You can either block the users:
|
||||
users.each { |user| user.blocked? ? nil : user.block! }
|
||||
|
||||
# Or you can delete them:
|
||||
# need 'current user' (your user) for auditing purposes
|
||||
current_user = User.find_by(username: '<your username>')
|
||||
|
||||
users.each do |user|
|
||||
DeleteUserWorker.perform_async(current_user.id, user.id)
|
||||
end
|
||||
```
|
||||
|
||||
### Deactivate Users that have no recent activity
|
||||
|
||||
```ruby
|
||||
days_inactive = 90
|
||||
inactive_users = User.active.where("last_activity_on <= ?", days_inactive.days.ago)
|
||||
|
||||
inactive_users.each do |user|
|
||||
puts "user '#{user.username}': #{user.last_activity_on}"
|
||||
user.deactivate!
|
||||
end
|
||||
```
|
||||
|
||||
### Block Users that have no recent activity
|
||||
|
||||
```ruby
|
||||
days_inactive = 90
|
||||
inactive_users = User.active.where("last_activity_on <= ?", days_inactive.days.ago)
|
||||
|
||||
inactive_users.each do |user|
|
||||
puts "user '#{user.username}': #{user.last_activity_on}"
|
||||
user.block!
|
||||
end
|
||||
```
|
||||
|
||||
### Find a user's max permissions for project/group
|
||||
|
||||
```ruby
|
||||
user = User.find_by_username 'username'
|
||||
project = Project.find_by_full_path 'group/project'
|
||||
user.max_member_access_for_project project.id
|
||||
```
|
||||
|
||||
```ruby
|
||||
user = User.find_by_username 'username'
|
||||
group = Group.find_by_full_path 'group'
|
||||
user.max_member_access_for_group group.id
|
||||
```
|
||||
|
||||
## Merge requests
|
||||
|
||||
## CI
|
||||
|
|
|
@ -85,7 +85,7 @@ In this mode, `jest` would resolve all the dependencies of related to the change
|
|||
|
||||
In addition, there are a few circumstances where we would always run the full Jest tests:
|
||||
|
||||
- when the `pipeline:run-all-jest` label is set on the merge request
|
||||
- when the `pipeline:run-all-jest` label is set on the merge request or is set by triage automation when the merge request is approved by any reviewer
|
||||
- when the merge request is created by an automation (for example, Gitaly update or MR targeting a stable branch)
|
||||
- when the merge request is created in a security mirror
|
||||
- when any CI configuration file is changed (for example, `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
|
|
|
@ -104,6 +104,8 @@ instead of the Rails console.
|
|||
Using the [Rails console](../administration/operations/rails_console.md), 2FA for a single user can be disabled.
|
||||
Connect to the Rails console and run:
|
||||
|
||||
**In GitLab 13.5 and later:**
|
||||
|
||||
```ruby
|
||||
admin = User.find_by_username('<USERNAME>')
|
||||
user_to_disable = User.find_by_username('<USERNAME>')
|
||||
|
@ -111,6 +113,9 @@ user_to_disable = User.find_by_username('<USERNAME>')
|
|||
TwoFactor::DestroyService.new(admin, user: user_to_disable).execute
|
||||
```
|
||||
|
||||
NOTE:
|
||||
The target user is notified that 2FA has been disabled.
|
||||
|
||||
### For all users
|
||||
|
||||
There may be some special situations where you want to disable 2FA for everyone
|
||||
|
|
|
@ -460,3 +460,40 @@ If your credit card is declined when purchasing a GitLab subscription, possible
|
|||
|
||||
Check with your financial institution to confirm if any of these reasons apply. If they don't
|
||||
apply, contact [GitLab Support](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293).
|
||||
|
||||
### Check daily and historical billable users
|
||||
|
||||
You can get a list of daily and historical billable users in your GitLab instance.
|
||||
|
||||
1. [Start a rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
|
||||
1. Count the number of users in the instance:
|
||||
|
||||
```ruby
|
||||
User.billable.count
|
||||
```
|
||||
|
||||
1. Get the historical maximum number of users on the instance from the past year:
|
||||
|
||||
```ruby
|
||||
::HistoricalData.max_historical_user_count(from: 1.year.ago.beginning_of_day, to: Time.current.end_of_day)
|
||||
```
|
||||
|
||||
### Update daily billable and historical users
|
||||
|
||||
You can trigger a manual update of the daily and historical billable users in your GitLab instance.
|
||||
|
||||
1. [Start a rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
|
||||
1. Force an update of the daily billable users:
|
||||
|
||||
```ruby
|
||||
identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users]
|
||||
::Analytics::UsageTrends::CounterJobWorker.new.perform(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now)
|
||||
```
|
||||
|
||||
1. Force an update of the historical max billable users:
|
||||
|
||||
```ruby
|
||||
::HistoricalDataWorker.new.perform
|
||||
```
|
||||
|
|
|
@ -283,3 +283,62 @@ You can also delete a user and their contributions, such as merge requests, issu
|
|||
|
||||
NOTE:
|
||||
Before 15.1, additionally groups of which deleted user were the only owner among direct members were deleted.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
When moderating users, you may need to perform bulk actions on them based on certain conditions. The following rails console scripts show some examples of this. You may [start a rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session) and use scripts similar to the following:
|
||||
|
||||
### Deactivate Users that have no recent activity
|
||||
|
||||
WARNING:
|
||||
Commands that change data can cause damage if not run correctly or under the right conditions. Always run commands in a test environment first and have a backup instance ready to restore.
|
||||
|
||||
```ruby
|
||||
days_inactive = 90
|
||||
inactive_users = User.active.where("last_activity_on <= ?", days_inactive.days.ago)
|
||||
|
||||
inactive_users.each do |user|
|
||||
puts "user '#{user.username}': #{user.last_activity_on}"
|
||||
user.deactivate!
|
||||
end
|
||||
```
|
||||
|
||||
### Block Users that have no recent activity
|
||||
|
||||
WARNING:
|
||||
Commands that change data can cause damage if not run correctly or under the right conditions. Always run commands in a test environment first and have a backup instance ready to restore.
|
||||
|
||||
```ruby
|
||||
days_inactive = 90
|
||||
inactive_users = User.active.where("last_activity_on <= ?", days_inactive.days.ago)
|
||||
|
||||
inactive_users.each do |user|
|
||||
puts "user '#{user.username}': #{user.last_activity_on}"
|
||||
user.block!
|
||||
end
|
||||
```
|
||||
|
||||
### Block or Delete Users that have no projects or groups
|
||||
|
||||
WARNING:
|
||||
Commands that change data can cause damage if not run correctly or under the right conditions. Always run commands in a test environment first and have a backup instance ready to restore.
|
||||
|
||||
```ruby
|
||||
users = User.where('id NOT IN (select distinct(user_id) from project_authorizations)')
|
||||
|
||||
# How many users are removed?
|
||||
users.count
|
||||
|
||||
# If that count looks sane:
|
||||
|
||||
# You can either block the users:
|
||||
users.each { |user| user.blocked? ? nil : user.block! }
|
||||
|
||||
# Or you can delete them:
|
||||
# need 'current user' (your user) for auditing purposes
|
||||
current_user = User.find_by(username: '<your username>')
|
||||
|
||||
users.each do |user|
|
||||
DeleteUserWorker.perform_async(current_user.id, user.id)
|
||||
end
|
||||
```
|
||||
|
|
|
@ -859,3 +859,17 @@ Commands that change data can cause damage if not run correctly or under the rig
|
|||
```ruby
|
||||
GroupDestroyWorker.new.perform(group_id, user_id)
|
||||
```
|
||||
|
||||
### Find a user's max permissions for a group or project
|
||||
|
||||
```ruby
|
||||
user = User.find_by_username 'username'
|
||||
project = Project.find_by_full_path 'group/project'
|
||||
user.max_member_access_for_project project.id
|
||||
```
|
||||
|
||||
```ruby
|
||||
user = User.find_by_username 'username'
|
||||
group = Group.find_by_full_path 'group'
|
||||
user.max_member_access_for_group group.id
|
||||
```
|
||||
|
|
|
@ -49,3 +49,16 @@ Users are:
|
|||
- Created when first signing with [Group SAML](../../group/saml_sso/index.md).
|
||||
- Automatically created by [SCIM](../../group/saml_sso/scim_setup.md) when the user is created in
|
||||
the identity provider.
|
||||
|
||||
## Create users through the Rails console
|
||||
|
||||
WARNING:
|
||||
Commands that change data can cause damage if not run correctly or under the right conditions. Always run commands in a test environment first and have a backup instance ready to restore.
|
||||
|
||||
To create a user through the rails console, [start a console session](../../../administration/operations/rails_console.md#starting-a-rails-console-session) and run the following commands:
|
||||
|
||||
```ruby
|
||||
u = User.new(username: 'test_user', email: 'test@example.com', name: 'Test User', password: 'password', password_confirmation: 'password')
|
||||
u.skip_confirmation! # Use it only if you wish user to be automatically confirmed. If skipped, user receives confirmation e-mail
|
||||
u.save!
|
||||
```
|
||||
|
|
|
@ -171,6 +171,7 @@ module API
|
|||
namespace do
|
||||
mount ::API::AccessRequests
|
||||
mount ::API::Appearance
|
||||
mount ::API::BulkImports
|
||||
mount ::API::Ci::Runner
|
||||
mount ::API::Clusters::Agents
|
||||
mount ::API::Clusters::AgentTokens
|
||||
|
@ -207,7 +208,6 @@ module API
|
|||
mount ::API::Boards
|
||||
mount ::API::Branches
|
||||
mount ::API::BroadcastMessages
|
||||
mount ::API::BulkImports
|
||||
mount ::API::Ci::JobArtifacts
|
||||
mount ::API::Ci::Jobs
|
||||
mount ::API::Ci::PipelineSchedules
|
||||
|
|
|
@ -41,7 +41,15 @@ module API
|
|||
resource :bulk_imports do
|
||||
desc 'Start a new GitLab Migration' do
|
||||
detail 'This feature was introduced in GitLab 14.2.'
|
||||
success Entities::BulkImport
|
||||
success code: 200, model: Entities::BulkImport
|
||||
consumes ['application/x-www-form-urlencoded']
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 400, message: 'Bad request' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 422, message: 'Unprocessable entity' },
|
||||
{ code: 503, message: 'Service unavailable' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
requires :configuration, type: Hash, desc: 'The source GitLab instance configuration' do
|
||||
|
@ -88,7 +96,13 @@ module API
|
|||
|
||||
desc 'List all GitLab Migrations' do
|
||||
detail 'This feature was introduced in GitLab 14.1.'
|
||||
success Entities::BulkImport
|
||||
is_array true
|
||||
success code: 200, model: Entities::BulkImport
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 503, message: 'Service unavailable' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -103,7 +117,13 @@ module API
|
|||
|
||||
desc "List all GitLab Migrations' entities" do
|
||||
detail 'This feature was introduced in GitLab 14.1.'
|
||||
success Entities::BulkImports::Entity
|
||||
is_array true
|
||||
success code: 200, model: Entities::BulkImports::Entity
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 503, message: 'Service unavailable' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -123,7 +143,12 @@ module API
|
|||
|
||||
desc 'Get GitLab Migration details' do
|
||||
detail 'This feature was introduced in GitLab 14.1.'
|
||||
success Entities::BulkImport
|
||||
success code: 200, model: Entities::BulkImport
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 503, message: 'Service unavailable' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
requires :import_id, type: Integer, desc: "The ID of user's GitLab Migration"
|
||||
|
@ -134,7 +159,13 @@ module API
|
|||
|
||||
desc "List GitLab Migration entities" do
|
||||
detail 'This feature was introduced in GitLab 14.1.'
|
||||
success Entities::BulkImports::Entity
|
||||
is_array true
|
||||
success code: 200, model: Entities::BulkImports::Entity
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 503, message: 'Service unavailable' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
requires :import_id, type: Integer, desc: "The ID of user's GitLab Migration"
|
||||
|
@ -148,7 +179,12 @@ module API
|
|||
|
||||
desc 'Get GitLab Migration entity details' do
|
||||
detail 'This feature was introduced in GitLab 14.1.'
|
||||
success Entities::BulkImports::Entity
|
||||
success code: 200, model: Entities::BulkImports::Entity
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 503, message: 'Service unavailable' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
requires :import_id, type: Integer, desc: "The ID of user's GitLab Migration"
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
module API
|
||||
module Entities
|
||||
class BulkImport < Grape::Entity
|
||||
expose :id
|
||||
expose :status_name, as: :status
|
||||
expose :source_type
|
||||
expose :created_at
|
||||
expose :updated_at
|
||||
expose :id, documentation: { type: 'integer', example: 1 }
|
||||
expose :status_name, as: :status, documentation: {
|
||||
type: 'string', example: 'finished', values: %w[created started finished timeout failed]
|
||||
}
|
||||
expose :source_type, documentation: { type: 'string', example: 'gitlab' }
|
||||
expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' }
|
||||
expose :updated_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,19 +4,21 @@ module API
|
|||
module Entities
|
||||
module BulkImports
|
||||
class Entity < Grape::Entity
|
||||
expose :id
|
||||
expose :bulk_import_id
|
||||
expose :status_name, as: :status
|
||||
expose :source_full_path
|
||||
expose :destination_name # deprecated
|
||||
expose :destination_slug
|
||||
expose :destination_namespace
|
||||
expose :parent_id
|
||||
expose :namespace_id
|
||||
expose :project_id
|
||||
expose :created_at
|
||||
expose :updated_at
|
||||
expose :failures, using: EntityFailure
|
||||
expose :id, documentation: { type: 'integer', example: 1 }
|
||||
expose :bulk_import_id, documentation: { type: 'integer', example: 1 }
|
||||
expose :status_name, as: :status, documentation: {
|
||||
type: 'string', example: 'created', values: %w[created started finished timeout failed]
|
||||
}
|
||||
expose :source_full_path, documentation: { type: 'string', example: 'source_group' }
|
||||
expose :destination_name, documentation: { type: 'string', example: 'destination_slug' } # deprecated
|
||||
expose :destination_slug, documentation: { type: 'string', example: 'destination_slug' }
|
||||
expose :destination_namespace, documentation: { type: 'string', example: 'destination_path' }
|
||||
expose :parent_id, documentation: { type: 'integer', example: 1 }
|
||||
expose :namespace_id, documentation: { type: 'integer', example: 1 }
|
||||
expose :project_id, documentation: { type: 'integer', example: 1 }
|
||||
expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' }
|
||||
expose :updated_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' }
|
||||
expose :failures, using: EntityFailure, documentation: { is_array: true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,16 +4,18 @@ module API
|
|||
module Entities
|
||||
module BulkImports
|
||||
class EntityFailure < Grape::Entity
|
||||
expose :relation
|
||||
expose :pipeline_step, as: :step
|
||||
expose :exception_message do |failure|
|
||||
expose :relation, documentation: { type: 'string', example: 'group' }
|
||||
expose :pipeline_step, as: :step, documentation: { type: 'string', example: 'extractor' }
|
||||
expose :exception_message, documentation: { type: 'string', example: 'error message' } do |failure|
|
||||
::Projects::ImportErrorFilter.filter_message(failure.exception_message.truncate(72))
|
||||
end
|
||||
expose :exception_class
|
||||
expose :correlation_id_value
|
||||
expose :created_at
|
||||
expose :pipeline_class
|
||||
expose :pipeline_step
|
||||
expose :exception_class, documentation: { type: 'string', example: 'Exception' }
|
||||
expose :correlation_id_value, documentation: { type: 'string', example: 'dfcf583058ed4508e4c7c617bd7f0edd' }
|
||||
expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' }
|
||||
expose :pipeline_class, documentation: {
|
||||
type: 'string', example: 'BulkImports::Groups::Pipelines::GroupPipeline'
|
||||
}
|
||||
expose :pipeline_step, documentation: { type: 'string', example: 'extractor' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
35
spec/frontend/vue_shared/alert_details/router_spec.js
Normal file
35
spec/frontend/vue_shared/alert_details/router_spec.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import createRouter from '~/vue_shared/alert_details/router';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
|
||||
const BASE_PATH = '/-/alert_management/1/details';
|
||||
const EMPTY_HASH = '';
|
||||
const NOOP = () => {};
|
||||
|
||||
describe('AlertDetails router', () => {
|
||||
const originalLocation = window.location.href;
|
||||
let router;
|
||||
|
||||
beforeEach(() => {
|
||||
setWindowLocation(originalLocation);
|
||||
router = createRouter(BASE_PATH);
|
||||
});
|
||||
|
||||
describe('redirects hash route mode URLs to history route mode', () => {
|
||||
it.each`
|
||||
hashPath | historyPath
|
||||
${'/#/overview'} | ${'/overview'}
|
||||
${'#/overview'} | ${'/overview'}
|
||||
${'/#/'} | ${'/'}
|
||||
${'#/'} | ${'/'}
|
||||
${'/#'} | ${'/'}
|
||||
${'#'} | ${'/'}
|
||||
${'/'} | ${'/'}
|
||||
${'/overview'} | ${'/overview'}
|
||||
`('should redirect "$hashPath" to "$historyPath"', ({ hashPath, historyPath }) => {
|
||||
router.push(hashPath, NOOP);
|
||||
|
||||
expect(window.location.hash).toBe(EMPTY_HASH);
|
||||
expect(window.location.pathname).toBe(BASE_PATH + historyPath);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue