Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1123408ec8
commit
4db74ea147
26 changed files with 568 additions and 150 deletions
|
@ -291,6 +291,12 @@ Gitlab/AvoidUploadedFileFromParams:
|
|||
- 'spec/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
|
||||
Gitlab/EventStoreSubscriber:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
|
||||
GitlabSecurity/PublicSend:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
|
|
|
@ -41,6 +41,16 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
inputFieldName: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'upload_file',
|
||||
},
|
||||
shouldUpdateInputOnFileDrop: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -84,6 +94,30 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
// NOTE: This is a temporary solution to integrate dropzone into a Rails
|
||||
// form. On file drop if `shouldUpdateInputOnFileDrop` is true, the file
|
||||
// input value is updated. So that when the form is submitted — the file
|
||||
// value would be send together with the form data. This solution should
|
||||
// be removed when License file upload page is fully migrated:
|
||||
// https://gitlab.com/gitlab-org/gitlab/-/issues/352501
|
||||
// NOTE: as per https://caniuse.com/mdn-api_htmlinputelement_files, IE11
|
||||
// is not able to set input.files property, thought the user would still
|
||||
// be able to use the file picker dialogue option, by clicking the
|
||||
// "openFileUpload" button
|
||||
if (this.shouldUpdateInputOnFileDrop) {
|
||||
// Since FileList cannot be easily manipulated, to match requirement of
|
||||
// singleFileSelection, we're throwing an error if multiple files were
|
||||
// dropped on the dropzone
|
||||
// NOTE: we can drop this logic together with
|
||||
// `shouldUpdateInputOnFileDrop` flag
|
||||
if (this.singleFileSelection && files.length > 1) {
|
||||
this.$emit('error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$refs.fileUpload.files = files;
|
||||
}
|
||||
|
||||
this.$emit('change', this.singleFileSelection ? files[0] : files);
|
||||
},
|
||||
ondragenter(e) {
|
||||
|
@ -116,6 +150,7 @@ export default {
|
|||
<slot>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
@click="openFileUpload"
|
||||
>
|
||||
<div
|
||||
|
@ -147,7 +182,7 @@ export default {
|
|||
<input
|
||||
ref="fileUpload"
|
||||
type="file"
|
||||
name="upload_file"
|
||||
:name="inputFieldName"
|
||||
:accept="validFileMimetypes"
|
||||
class="hide"
|
||||
:multiple="!singleFileSelection"
|
||||
|
|
|
@ -15,6 +15,7 @@ class ContainerRepository < ApplicationRecord
|
|||
MIGRATION_STATES = (IDLE_MIGRATION_STATES + ACTIVE_MIGRATION_STATES).freeze
|
||||
|
||||
TooManyImportsError = Class.new(StandardError)
|
||||
NativeImportError = Class.new(StandardError)
|
||||
|
||||
belongs_to :project
|
||||
|
||||
|
@ -85,9 +86,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
|
||||
state :pre_import_done do
|
||||
validates :migration_pre_import_started_at,
|
||||
:migration_pre_import_done_at,
|
||||
presence: true
|
||||
validates :migration_pre_import_done_at, presence: true
|
||||
end
|
||||
|
||||
state :importing do
|
||||
|
@ -113,7 +112,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
|
||||
event :finish_pre_import do
|
||||
transition pre_importing: :pre_import_done
|
||||
transition %i[pre_importing import_aborted] => :pre_import_done
|
||||
end
|
||||
|
||||
event :start_import do
|
||||
|
@ -121,7 +120,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
|
||||
event :finish_import do
|
||||
transition importing: :import_done
|
||||
transition %i[importing import_aborted] => :import_done
|
||||
end
|
||||
|
||||
event :already_migrated do
|
||||
|
@ -155,7 +154,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
before_transition pre_importing: :pre_import_done do |container_repository|
|
||||
before_transition %i[pre_importing import_aborted] => :pre_import_done do |container_repository|
|
||||
container_repository.migration_pre_import_done_at = Time.zone.now
|
||||
end
|
||||
|
||||
|
@ -170,7 +169,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
before_transition importing: :import_done do |container_repository|
|
||||
before_transition %i[importing import_aborted] => :import_done do |container_repository|
|
||||
container_repository.migration_import_done_at = Time.zone.now
|
||||
end
|
||||
|
||||
|
@ -272,13 +271,29 @@ class ContainerRepository < ApplicationRecord
|
|||
finish_pre_import && start_import
|
||||
end
|
||||
|
||||
def retry_migration
|
||||
return if migration_import_done_at
|
||||
def retry_aborted_migration
|
||||
return unless migration_state == 'import_aborted'
|
||||
|
||||
if migration_pre_import_done_at
|
||||
import_status = gitlab_api_client.import_status(self.path)
|
||||
|
||||
case import_status
|
||||
when 'native'
|
||||
raise NativeImportError
|
||||
when 'import_in_progress'
|
||||
nil
|
||||
when 'import_complete'
|
||||
finish_import
|
||||
when 'import_failed'
|
||||
retry_import
|
||||
else
|
||||
when 'pre_import_in_progress'
|
||||
nil
|
||||
when 'pre_import_complete'
|
||||
finish_pre_import_and_start_import
|
||||
when 'pre_import_failed'
|
||||
retry_pre_import
|
||||
else
|
||||
# If the import_status request fails, use the timestamp to guess current state
|
||||
migration_pre_import_done_at ? retry_import : retry_pre_import
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
%a{ href: help_page_path('user/usage_quotas.md'), target: '_blank', rel: 'noopener noreferrer' }
|
||||
= s_('UsageQuota|Learn more about usage quotas') + '.'
|
||||
|
||||
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
|
||||
%ul.nav.nav-tabs.nav-links.scrolling-tabs.separator.js-usage-quota-tabs{ role: 'tablist' }
|
||||
%li.nav-item
|
||||
%a.nav-link#storage-quota{ data: { toggle: "tab", action: '#storage-quota-tab' }, href: '#storage-quota-tab', 'aria-controls': '#storage-quota-tab', 'aria-selected': 'true' }
|
||||
= s_('UsageQuota|Storage')
|
||||
= gl_tabs_nav do
|
||||
= gl_tab_link_to '#storage-quota-tab', item_active: true do
|
||||
= s_('UsageQuota|Storage')
|
||||
|
||||
.tab-content
|
||||
.tab-pane#storage-quota-tab
|
||||
.tab-pane.active#storage-quota-tab
|
||||
#js-project-storage-count-app{ data: { project_path: @project.full_path } }
|
||||
|
|
|
@ -32,7 +32,7 @@ module ContainerRegistry
|
|||
private
|
||||
|
||||
def handle_aborted_migration
|
||||
return unless next_aborted_repository&.retry_migration
|
||||
return unless next_aborted_repository&.retry_aborted_migration
|
||||
|
||||
log_extra_metadata_on_done(:container_repository_id, next_aborted_repository.id)
|
||||
log_extra_metadata_on_done(:import_type, 'retry')
|
||||
|
|
|
@ -4,77 +4,69 @@ group: Distribution
|
|||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# How to self-host the docs site **(FREE SELF)**
|
||||
# How to host the GitLab product documentation **(FREE SELF)**
|
||||
|
||||
If you have a self-managed instance of GitLab, you may not be able to access the
|
||||
product documentation as hosted on `docs.gitlab.com` from your GitLab instance.
|
||||
|
||||
Be aware of the following items if you self-host the product documentation:
|
||||
|
||||
- You must host the product documentation site under a subdirectory that matches
|
||||
your installed GitLab version (for example, `14.5/`). The
|
||||
[Docker images](https://gitlab.com/gitlab-org/gitlab-docs/container_registry/631635)
|
||||
hosted by the GitLab Docs team provide this by default. We use a
|
||||
[script](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/2995d1378175803b22fb8806ba77adf63e79f32c/scripts/normalize-links.sh#L28-82)
|
||||
to normalize the links and prefix them with the respective version.
|
||||
- The version dropdown will display additional versions that don't exist, selecting
|
||||
those versions will display a 404 Not Found page.
|
||||
- Results when using the search box will display results from `docs.gitlab.com`
|
||||
and not the local documentation.
|
||||
- When you use the Docker images to serve the product documentation site, by
|
||||
default the landing page redirects to the respective version (for example, `/14.5/`),
|
||||
which causes the landing page <https://docs.gitlab.com> to not be displayed.
|
||||
If you are not able to access the GitLab product documentation at `docs.gitlab.com`,
|
||||
you can host the documentation yourself instead.
|
||||
|
||||
## Documentation self-hosting options
|
||||
|
||||
You can self-host the GitLab product documentation locally using one of these
|
||||
methods:
|
||||
To host the GitLab product documentation, you can use:
|
||||
|
||||
- Docker
|
||||
- A Docker container
|
||||
- GitLab Pages
|
||||
- From your own webserver
|
||||
- Your own web server
|
||||
|
||||
The examples on this page are based on GitLab 14.5.
|
||||
After you create a website by using one of these methods, you redirect the UI links
|
||||
in the product to point to your website.
|
||||
|
||||
NOTE:
|
||||
The website you create must be hosted under a subdirectory that matches
|
||||
your installed GitLab version (for example, `14.5/`). The
|
||||
[Docker images](https://gitlab.com/gitlab-org/gitlab-docs/container_registry/631635)
|
||||
use this version by default.
|
||||
|
||||
The following examples use GitLab 14.5.
|
||||
|
||||
### Self-host the product documentation with Docker
|
||||
|
||||
The Docker images use a built-in webserver listening on port `4000`, so you need
|
||||
to expose that.
|
||||
You can run the GitLab product documentation website in a Docker container:
|
||||
|
||||
In the server that you host GitLab, or any other server that your GitLab instance
|
||||
can talk to, you can use Docker to pull the docs site:
|
||||
1. Expose port `4000`. The Docker image uses this port for the web server.
|
||||
1. On the server where you host GitLab, or on any other server that your GitLab instance
|
||||
can communicate with, pull the docs site:
|
||||
|
||||
```shell
|
||||
docker run -it --rm -p 4000:4000 registry.gitlab.com/gitlab-org/gitlab-docs:14.5
|
||||
```
|
||||
```shell
|
||||
docker run -it --rm -p 4000:4000 registry.gitlab.com/gitlab-org/gitlab-docs:14.5
|
||||
```
|
||||
|
||||
If you use [Docker compose](../install/docker.md#install-gitlab-using-docker-compose)
|
||||
to host your GitLab instance, add the following to `docker-compose.yaml`:
|
||||
If you host your GitLab instance using [Docker compose](../install/docker.md#install-gitlab-using-docker-compose),
|
||||
add the following to `docker-compose.yaml`:
|
||||
|
||||
```yaml
|
||||
version: '3.6'
|
||||
services:
|
||||
docs:
|
||||
image: registry.gitlab.com/gitlab-org/gitlab-docs:14.5
|
||||
hostname: 'https://gitlab.example.com'
|
||||
ports:
|
||||
- '4000:4000'
|
||||
```
|
||||
```yaml
|
||||
version: '3.6'
|
||||
services:
|
||||
docs:
|
||||
image: registry.gitlab.com/gitlab-org/gitlab-docs:14.5
|
||||
hostname: 'https://gitlab.example.com'
|
||||
ports:
|
||||
- '4000:4000'
|
||||
```
|
||||
|
||||
### Self-host the product documentation with GitLab Pages
|
||||
|
||||
You use GitLab Pages to host the GitLab product documentation locally.
|
||||
You can use GitLab Pages to host the GitLab product documentation.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- The Pages site URL must not use a subfolder. Due to the nature of how the docs
|
||||
- Ensure the Pages site URL does not use a subfolder. Because of how the docs
|
||||
site is pre-compiled, the CSS and JavaScript files are relative to the
|
||||
main domain or subdomain. For example, URLs like `https://example.com/docs/`
|
||||
are not supported.
|
||||
|
||||
To host the product documentation site with GitLab Pages:
|
||||
|
||||
1. [Create a new blank project](../user/project/working_with_projects.md#create-a-blank-project).
|
||||
1. [Create a blank project](../user/project/working_with_projects.md#create-a-blank-project).
|
||||
1. Create a new or edit your existing `.gitlab-ci.yml` file, and add the following
|
||||
`pages` job, while ensuring the version is the same as your GitLab installation:
|
||||
|
||||
|
@ -97,13 +89,13 @@ To host the product documentation site with GitLab Pages:
|
|||
| [Project website](../user/project/pages/getting_started_part_one.md#project-website-examples) | Not supported | Supported |
|
||||
| [User or group website](../user/project/pages/getting_started_part_one.md#user-and-group-website-examples) | Supported | Supported |
|
||||
|
||||
### Self-host the product documentation on your own webserver
|
||||
### Self-host the product documentation on your own web server
|
||||
|
||||
Because the product documentation site is static, you can grab the directory from
|
||||
the container (in `/usr/share/nginx/html`) and use your own web server to host
|
||||
it wherever you want.
|
||||
Because the product documentation site is static, from the container, you can take the contents
|
||||
of `/usr/share/nginx/html` and use your own web server to host
|
||||
the docs wherever you want.
|
||||
|
||||
Use the following commands, and replace `<destination>` with the directory where the
|
||||
Run the following commands, replacing `<destination>` with the directory where the
|
||||
documentation files will be copied to:
|
||||
|
||||
```shell
|
||||
|
@ -114,18 +106,30 @@ docker rm -f gitlab-docs
|
|||
|
||||
## Redirect the `/help` links to the new docs page
|
||||
|
||||
After your local product documentation site is running, [redirect the help
|
||||
links](../user/admin_area/settings/help_page.md#redirect-help-pages) in the GitLab
|
||||
application to your local site.
|
||||
After your local product documentation site is running,
|
||||
[redirect the help links](../user/admin_area/settings/help_page.md#redirect-help-pages)
|
||||
in the GitLab application to your local site.
|
||||
|
||||
Be sure to use the fully qualified domain name as the docs URL. For example, if you
|
||||
used the [Docker method](#self-host-the-product-documentation-with-docker), enter `http://0.0.0.0:4000`.
|
||||
|
||||
You don't need to append the version, as GitLab will detect it and append it to
|
||||
any documentation URL requests, as needed. For example, if your GitLab version is
|
||||
14.5, the GitLab Docs URL becomes `http://0.0.0.0:4000/14.5/`. The link
|
||||
inside GitLab displays as `<instance_url>/help/user/admin_area/settings/help_page#destination-requirements`,
|
||||
but when you select it, you are redirected to
|
||||
You don't need to append the version. GitLab detects it and appends it to
|
||||
documentation URL requests as needed. For example, if your GitLab version is
|
||||
14.5:
|
||||
|
||||
- The GitLab Docs URL becomes `http://0.0.0.0:4000/14.5/`.
|
||||
- The link in GitLab displays as `<instance_url>/help/user/admin_area/settings/help_page#destination-requirements`.
|
||||
- When you select the link, you are redirected to
|
||||
`http://0.0.0.0:4000/14.5/ee/user/admin_area/settings/help_page/#destination-requirements`.
|
||||
|
||||
To test the setting, select a **Learn more** link within the GitLab application.
|
||||
|
||||
## Known issues
|
||||
|
||||
If you self-host the product documentation:
|
||||
|
||||
- The version dropdown displays additional versions that don't exist. Selecting
|
||||
these versions displays a `404 Not Found` page.
|
||||
- The search displays results from `docs.gitlab.com` and not the local site.
|
||||
- By default, the landing page redirects to the
|
||||
respective version (for example, `/14.5/`). This causes the landing page <https://docs.gitlab.com> to not be displayed.
|
||||
|
|
|
@ -62,8 +62,8 @@ can reserve your catch-all mailbox for other purposes.
|
|||
|
||||
### Dedicated email address
|
||||
|
||||
This solution is relatively simple to set up: you just need to create an email
|
||||
address dedicated to receive your users' replies to GitLab notifications. However,
|
||||
To set up this solution, you must create a dedicated email
|
||||
address to receive your users' replies to GitLab notifications. However,
|
||||
this method only supports replies, and not the other features of [incoming email](#incoming-email).
|
||||
|
||||
## Accepted headers
|
||||
|
@ -75,7 +75,7 @@ Email is processed correctly when a configured email address is present in one o
|
|||
- `Envelope-To` or `X-Envelope-To`
|
||||
|
||||
In GitLab 14.6 and later, [Service Desk](../user/project/service_desk.md)
|
||||
also checks these additional headers.
|
||||
also checks accepted headers.
|
||||
|
||||
Usually, the "To" field contains the email address of the primary receiver.
|
||||
However, it might not include the configured GitLab email address if:
|
||||
|
@ -84,6 +84,14 @@ However, it might not include the configured GitLab email address if:
|
|||
- The address was included when using "Reply all".
|
||||
- The email was forwarded.
|
||||
|
||||
## Rejected headers
|
||||
|
||||
To prevent unwanted issue creation from automatic email systems, GitLab ignores all incoming email
|
||||
containing the following headers:
|
||||
|
||||
- `Auto-Submitted` with a value other than `no`
|
||||
- `X-Autoreply` with a value of `yes`
|
||||
|
||||
## Set it up
|
||||
|
||||
If you want to use Gmail / Google Apps for incoming email, make sure you have
|
||||
|
|
|
@ -97,6 +97,7 @@ The [Quality Engineering - Enablement team](https://about.gitlab.com/handbook/en
|
|||
- Network latency on the test environments between components on all Cloud Providers were measured at <5ms. Note that this is shared as an observation and not as an implicit recommendation.
|
||||
- We aim to have a "test smart" approach where architectures tested have a good range that can also apply to others. Testing focuses on 10k Omnibus on GCP as the testing has shown this is a good bellwether for the other architectures and cloud providers as well as Cloud Native Hybrids.
|
||||
- Testing is done publicly and all results are shared.
|
||||
- For more information about performance testing at GitLab, read [how our QA team leverages GitLab’s performance testing tool (and you can too)](https://about.gitlab.com/blog/2020/02/18/how-were-building-up-performance-testing-of-gitlab/).
|
||||
|
||||
The following table details the testing done against the reference architectures along with the frequency and results. Additional testing is continuously evaluated, and the table is updated accordingly.
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ Server hooks run custom logic on the GitLab server. Users can use them to run Gi
|
|||
- Enforcing specific commit policies.
|
||||
- Performing tasks based on the state of the repository.
|
||||
|
||||
Server hooks use `pre-receive`, `post-receive`, and `update`
|
||||
Server hooks use `pre-receive`, `post-receive`, and `update`
|
||||
[Git server-side hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_server_side_hooks).
|
||||
|
||||
GitLab administrators configure server hooks on the file system of the GitLab server. If you don't have file system access,
|
||||
|
@ -124,8 +124,8 @@ The following Git environment variables are supported for `pre-receive` and `pos
|
|||
|:-----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `GIT_ALTERNATE_OBJECT_DIRECTORIES` | Alternate object directories in the quarantine environment. See [Git `receive-pack` documentation](https://git-scm.com/docs/git-receive-pack#_quarantine_environment). |
|
||||
| `GIT_OBJECT_DIRECTORY` | GitLab project path in the quarantine environment. See [Git `receive-pack` documentation](https://git-scm.com/docs/git-receive-pack#_quarantine_environment). |
|
||||
| `GIT_PUSH_OPTION_COUNT` | Number of push options. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
|
||||
| `GIT_PUSH_OPTION_<i>` | Value of push options where `i` is from `0` to `GIT_PUSH_OPTION_COUNT - 1`. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
|
||||
| `GIT_PUSH_OPTION_COUNT` | Number of [push options](../user/project/push_options.md). See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
|
||||
| `GIT_PUSH_OPTION_<i>` | Value of [push options](../user/project/push_options.md) where `i` is from `0` to `GIT_PUSH_OPTION_COUNT - 1`. See [Git `pre-receive` documentation](https://git-scm.com/docs/githooks#pre-receive). |
|
||||
|
||||
## Custom error messages
|
||||
|
||||
|
|
|
@ -683,6 +683,10 @@ Do not use profanity. Doing so may negatively affect other users and contributor
|
|||
|
||||
Use lowercase for **push rules**.
|
||||
|
||||
## register
|
||||
|
||||
Use **register** instead of **sign up** when talking about creating an account.
|
||||
|
||||
## Reporter
|
||||
|
||||
When writing about the Reporter role:
|
||||
|
@ -780,6 +784,10 @@ Use **sign in** instead of **sign on** or **log on** or **log in**. If the user
|
|||
|
||||
You can use **single sign-on**.
|
||||
|
||||
## sign up
|
||||
|
||||
Use **register** instead of **sign up** when talking about creating an account.
|
||||
|
||||
## simply, simple
|
||||
|
||||
Do not use **simply** or **simple**. If the user doesn't find the process to be simple, we lose their trust. ([Vale](../testing.md#vale) rule: [`Simplicity.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Simplicity.yml))
|
||||
|
|
|
@ -567,6 +567,7 @@ sudo -u git -H git config --global gc.auto 0
|
|||
sudo -u git -H git config --global repack.writeBitmaps true
|
||||
|
||||
# Enable push options
|
||||
# Refer to https://docs.gitlab.com/ee/user/project/push_options.html for more information.
|
||||
sudo -u git -H git config --global receive.advertisePushOptions true
|
||||
|
||||
# Enable fsyncObjectFiles to reduce risk of repository corruption if the server crashes
|
||||
|
@ -1143,7 +1144,7 @@ You can configure the Prometheus server in `config/gitlab.yml`:
|
|||
# example
|
||||
prometheus:
|
||||
enabled: true
|
||||
server_address: '10.1.2.3:9090'
|
||||
server_address: '10.1.2.3:9090'
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
@ -59,8 +59,10 @@ Otherwise, to upload your license:
|
|||
1. On the left sidebar, select **Settings**.
|
||||
1. In the **License file** area, select **Upload a license**.
|
||||
1. Upload a license:
|
||||
- For a file, select **Upload `.gitlab-license` file**, **Choose file**, and
|
||||
select the license file from your local machine.
|
||||
- For a file, either:
|
||||
- Select **Upload `.gitlab-license` file**, then **Choose File** and
|
||||
select the license file from your local machine.
|
||||
- Drag and drop the license file to the **Drag your license file here** area.
|
||||
- For plain text, select **Enter license key** and paste the contents in
|
||||
**License key**.
|
||||
1. Select the **Terms of Service** checkbox.
|
||||
|
|
|
@ -137,3 +137,4 @@ For a web developer writing a webpage for your company's website:
|
|||
- [Suggest code changes](reviews/suggestions.md)
|
||||
- [Commits](commits.md)
|
||||
- [CI/CD pipelines](../../../ci/index.md)
|
||||
- [Push options](../push_options.md) for merge requests
|
||||
|
|
|
@ -57,8 +57,8 @@ GitLab administrators can configure a new default branch name at the
|
|||
|
||||
### Instance-level custom initial branch name **(FREE SELF)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221013) in GitLab 13.2.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/325163) in GitLab 13.12.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221013) in GitLab 13.2 [with a flag](../../../../administration/feature_flags.md) named `global_default_branch_name`. Enabled by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/325163) in GitLab 13.12. Feature flag `global_default_branch_name` removed.
|
||||
|
||||
GitLab [administrators](../../../permissions.md) of self-managed instances can
|
||||
customize the initial branch for projects hosted on that instance. Individual
|
||||
|
|
|
@ -33,7 +33,7 @@ To fork an existing project in GitLab:
|
|||
![Choose namespace](img/forking_workflow_choose_namespace_v13_10.png)
|
||||
|
||||
- Experimental method. If your GitLab administrator has
|
||||
[enabled the experimental fork project form](#enable-or-disable-the-fork-project-form), read
|
||||
enabled the experimental fork project form, read
|
||||
[Create a fork with the fork project form](#create-a-fork-with-the-fork-project-form).
|
||||
Only namespaces where you have at least the Developer role for are shown.
|
||||
|
||||
|
@ -84,14 +84,14 @@ You can unlink your fork from its upstream project in the [advanced settings](..
|
|||
|
||||
## Create a fork with the fork project form **(FREE SELF)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15013) in GitLab 13.11.
|
||||
> - It's [deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-the-fork-project-form). **(FREE SELF)**
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15013) in GitLab 13.11 [with a flag](../../../administration/feature_flags.md) named `fork_project_form`. Disabled by default.
|
||||
> - [Enabled on self-managed and GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64967) in GitLab 13.8.
|
||||
|
||||
This experimental version of the fork project form is available only if your GitLab
|
||||
administrator has [enabled it](#enable-or-disable-the-fork-project-form):
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `fork_project_form`.
|
||||
On GitLab.com, this feature is available.
|
||||
|
||||
This version of the fork project form is experimental:
|
||||
|
||||
![Choose namespace](img/fork_form_v13_10.png)
|
||||
|
||||
|
@ -102,23 +102,3 @@ To use it, follow the instructions at [Creating a fork](#creating-a-fork) and pr
|
|||
- The project slug.
|
||||
- Optional. The project description.
|
||||
- The visibility level for your fork.
|
||||
|
||||
### Enable or disable the fork project form **(FREE SELF)**
|
||||
|
||||
The new [fork project form](#create-a-fork-with-the-fork-project-form) is under
|
||||
development and not ready for production use. It is deployed behind a feature flag
|
||||
that is **disabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
|
||||
can enable it.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:fork_project_form)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:fork_project_form)
|
||||
```
|
||||
|
|
|
@ -333,3 +333,10 @@ Note that:
|
|||
|
||||
Behind the scenes, Service Desk works by the special Support Bot user creating issues. This user
|
||||
does not count toward the license limit count.
|
||||
|
||||
## Troubleshooting Service Desk
|
||||
|
||||
### Emails to Service Desk do not create issues
|
||||
|
||||
Your emails might be ignored because they contain one of the
|
||||
[email headers that GitLab ignores](../../administration/incoming_email.md#rejected-headers).
|
||||
|
|
|
@ -45,6 +45,11 @@ module ContainerRegistry
|
|||
IMPORT_RESPONSES.fetch(response.status, :error)
|
||||
end
|
||||
|
||||
def import_status(path)
|
||||
body_hash = response_body(faraday.get(import_url_for(path)))
|
||||
body_hash['status'] || 'error'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def start_import_for(path, pre:)
|
||||
|
|
|
@ -21660,9 +21660,18 @@ msgstr ""
|
|||
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|Drop your license file to start the upload."
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|Error: You are trying to upload something other than a file"
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|License Compliance"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21681,6 +21690,9 @@ msgstr ""
|
|||
msgid "Licenses|Specified policies in this project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|The file could not be uploaded."
|
||||
msgstr ""
|
||||
|
||||
msgid "Licenses|The license list details information about the licenses used within your project."
|
||||
msgstr ""
|
||||
|
||||
|
@ -40731,6 +40743,9 @@ msgstr ""
|
|||
msgid "Webhooks|An issue is created, updated, closed, or reopened."
|
||||
msgstr ""
|
||||
|
||||
msgid "Webhooks|Are you sure you want to delete this group hook?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Webhooks|Are you sure you want to delete this project hook?"
|
||||
msgstr ""
|
||||
|
||||
|
|
71
rubocop/cop/gitlab/event_store_subscriber.rb
Normal file
71
rubocop/cop/gitlab/event_store_subscriber.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Gitlab
|
||||
# Cop that checks the implementation of Gitlab::EventStore::Subscriber
|
||||
#
|
||||
# A worker that implements Gitlab::EventStore::Subscriber
|
||||
# must implement the method #handle_event(event) and
|
||||
# must not override the method #perform(*args)
|
||||
#
|
||||
# # bad
|
||||
# class MySubscriber
|
||||
# include Gitlab::EventStore::Subscriber
|
||||
#
|
||||
# def perform(*args)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # bad
|
||||
# class MySubscriber
|
||||
# include Gitlab::EventStore::Subscriber
|
||||
# end
|
||||
#
|
||||
# # good
|
||||
# class MySubscriber
|
||||
# include Gitlab::EventStore::Subscriber
|
||||
#
|
||||
# def handle_event(event)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
class EventStoreSubscriber < RuboCop::Cop::Cop
|
||||
SUBSCRIBER_MODULE_NAME = 'Gitlab::EventStore::Subscriber'
|
||||
FORBID_PERFORM_OVERRIDE = "Do not override `perform` in a `#{SUBSCRIBER_MODULE_NAME}`."
|
||||
REQUIRE_HANDLE_EVENT = "A `#{SUBSCRIBER_MODULE_NAME}` must implement `#handle_event(event)`."
|
||||
|
||||
def_node_matcher :includes_subscriber?, <<~PATTERN
|
||||
(send nil? :include (const (const (const nil? :Gitlab) :EventStore) :Subscriber))
|
||||
PATTERN
|
||||
|
||||
def on_send(node)
|
||||
return unless includes_subscriber?(node)
|
||||
|
||||
self.is_subscriber ||= true
|
||||
self.include_subscriber_node ||= node
|
||||
end
|
||||
|
||||
def on_def(node)
|
||||
if is_subscriber && node.method_name == :perform
|
||||
add_offense(node, message: FORBID_PERFORM_OVERRIDE)
|
||||
end
|
||||
|
||||
self.implements_handle_event ||= true if node.method_name == :handle_event
|
||||
end
|
||||
|
||||
def on_investigation_end
|
||||
super
|
||||
|
||||
if is_subscriber && !implements_handle_event
|
||||
add_offense(include_subscriber_node, message: REQUIRE_HANDLE_EVENT)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_accessor :is_subscriber, :include_subscriber_node, :implements_handle_event
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,6 +6,7 @@ exports[`Upload dropzone component correctly overrides description and drop mess
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
@ -86,6 +87,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
@ -170,6 +172,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
@ -254,6 +257,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
@ -339,6 +343,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
@ -424,6 +429,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
@ -509,6 +515,7 @@ exports[`Upload dropzone component when no slot provided renders default dropzon
|
|||
>
|
||||
<button
|
||||
class="card upload-dropzone-card upload-dropzone-border gl-w-full gl-h-full gl-align-items-center gl-justify-content-center gl-p-3"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-text-center gl-flex-direction-column"
|
||||
|
|
|
@ -16,6 +16,7 @@ describe('Upload dropzone component', () => {
|
|||
const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]');
|
||||
const findIcon = () => wrapper.find(GlIcon);
|
||||
const findUploadText = () => wrapper.find('[data-testid="upload-text"]').text();
|
||||
const findFileInput = () => wrapper.find('input[type="file"]');
|
||||
|
||||
function createComponent({ slots = {}, data = {}, props = {} } = {}) {
|
||||
wrapper = shallowMount(UploadDropzone, {
|
||||
|
@ -197,4 +198,60 @@ describe('Upload dropzone component', () => {
|
|||
|
||||
expect(wrapper.element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('file input form name', () => {
|
||||
it('applies inputFieldName as file input name', () => {
|
||||
createComponent({ props: { inputFieldName: 'test_field_name' } });
|
||||
expect(findFileInput().attributes('name')).toBe('test_field_name');
|
||||
});
|
||||
|
||||
it('uses default file input name if no inputFieldName provided', () => {
|
||||
createComponent();
|
||||
expect(findFileInput().attributes('name')).toBe('upload_file');
|
||||
});
|
||||
});
|
||||
|
||||
describe('updates file input files value', () => {
|
||||
// NOTE: the component assigns dropped files from the drop event to the
|
||||
// input.files property. There's a restriction that nothing but a FileList
|
||||
// can be assigned to this property. While FileList can't be created
|
||||
// manually: it has no constructor. And currently there's no good workaround
|
||||
// for jsdom. So we have to stub the file input in vm.$refs to ensure that
|
||||
// the files property is updated. This enforces following tests to know a
|
||||
// bit too much about the SUT internals See this thread for more details on
|
||||
// FileList in jsdom: https://github.com/jsdom/jsdom/issues/1272
|
||||
function stubFileInputOnWrapper() {
|
||||
const fakeFileInput = { files: [] };
|
||||
wrapper.vm.$refs.fileUpload = fakeFileInput;
|
||||
}
|
||||
|
||||
it('assigns dragged files to the input files property', async () => {
|
||||
const mockFile = { name: 'test', type: 'image/jpg' };
|
||||
const mockEvent = mockDragEvent({ files: [mockFile] });
|
||||
createComponent({ props: { shouldUpdateInputOnFileDrop: true } });
|
||||
stubFileInputOnWrapper();
|
||||
|
||||
wrapper.trigger('dragenter', mockEvent);
|
||||
await nextTick();
|
||||
wrapper.trigger('drop', mockEvent);
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.vm.$refs.fileUpload.files).toEqual([mockFile]);
|
||||
});
|
||||
|
||||
it('throws an error when multiple files are dropped on a single file input dropzone', async () => {
|
||||
const mockFile = { name: 'test', type: 'image/jpg' };
|
||||
const mockEvent = mockDragEvent({ files: [mockFile, mockFile] });
|
||||
createComponent({ props: { shouldUpdateInputOnFileDrop: true, singleFileSelection: true } });
|
||||
stubFileInputOnWrapper();
|
||||
|
||||
wrapper.trigger('dragenter', mockEvent);
|
||||
await nextTick();
|
||||
wrapper.trigger('drop', mockEvent);
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.vm.$refs.fileUpload.files).toEqual([]);
|
||||
expect(wrapper.emitted('error')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -77,7 +77,7 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#pre_import_repository' do
|
||||
describe '#import_repository' do
|
||||
subject { client.import_repository(path) }
|
||||
|
||||
where(:status_code, :expected_result) do
|
||||
|
@ -101,6 +101,26 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#import_status' do
|
||||
subject { client.import_status(path) }
|
||||
|
||||
before do
|
||||
stub_import_status(path, status)
|
||||
end
|
||||
|
||||
context 'with a status' do
|
||||
let(:status) { 'this_is_a_test' }
|
||||
|
||||
it { is_expected.to eq(status) }
|
||||
end
|
||||
|
||||
context 'with no status' do
|
||||
let(:status) { nil }
|
||||
|
||||
it { is_expected.to eq('error') }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.supports_gitlab_api?' do
|
||||
subject { described_class.supports_gitlab_api? }
|
||||
|
||||
|
@ -171,4 +191,14 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
|
|||
.with(headers: { 'Accept' => described_class::JSON_TYPE })
|
||||
.to_return(status: status_code, body: '')
|
||||
end
|
||||
|
||||
def stub_import_status(path, status)
|
||||
stub_request(:get, "#{registry_api_url}/gitlab/v1/import/#{path}/")
|
||||
.with(headers: { 'Accept' => described_class::JSON_TYPE })
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: { status: status }.to_json,
|
||||
headers: { content_type: 'application/json' }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -218,7 +218,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
|||
|
||||
subject { repository.finish_pre_import }
|
||||
|
||||
it_behaves_like 'transitioning from allowed states', %w[pre_importing]
|
||||
it_behaves_like 'transitioning from allowed states', %w[pre_importing import_aborted]
|
||||
|
||||
it 'sets migration_pre_import_done_at' do
|
||||
expect { subject }.to change { repository.reload.migration_pre_import_done_at }
|
||||
|
@ -263,7 +263,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
|||
|
||||
subject { repository.finish_import }
|
||||
|
||||
it_behaves_like 'transitioning from allowed states', %w[importing]
|
||||
it_behaves_like 'transitioning from allowed states', %w[importing import_aborted]
|
||||
it_behaves_like 'queueing the next import'
|
||||
|
||||
it 'sets migration_import_done_at and queues the next import' do
|
||||
|
@ -334,46 +334,120 @@ RSpec.describe ContainerRepository, :aggregate_failures do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'transitioning from allowed states', %w[pre_importing]
|
||||
it_behaves_like 'transitioning from allowed states', %w[pre_importing import_aborted]
|
||||
it_behaves_like 'transitioning to importing'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#retry_migration' do
|
||||
subject { repository.retry_migration }
|
||||
describe '#retry_aborted_migration' do
|
||||
subject { repository.retry_aborted_migration }
|
||||
|
||||
it 'retries the pre_import' do
|
||||
expect(repository).to receive(:retry_pre_import).and_return(true)
|
||||
expect(repository).not_to receive(:retry_import)
|
||||
|
||||
expect(subject).to eq(true)
|
||||
end
|
||||
|
||||
context 'when migration is done pre-importing' do
|
||||
before do
|
||||
repository.update_columns(migration_pre_import_done_at: Time.zone.now)
|
||||
end
|
||||
|
||||
it 'returns' do
|
||||
expect(repository).to receive(:retry_import).and_return(true)
|
||||
expect(repository).not_to receive(:retry_pre_import)
|
||||
|
||||
expect(subject).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when migration is already complete' do
|
||||
before do
|
||||
repository.update_columns(migration_import_done_at: Time.zone.now)
|
||||
end
|
||||
|
||||
it 'returns' do
|
||||
expect(repository).not_to receive(:retry_pre_import)
|
||||
expect(repository).not_to receive(:retry_import)
|
||||
shared_examples 'no action' do
|
||||
it 'does nothing' do
|
||||
expect { subject }.not_to change { repository.reload.migration_state }
|
||||
|
||||
expect(subject).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'retrying the pre_import' do
|
||||
it 'retries the pre_import' do
|
||||
expect(repository).to receive(:migration_pre_import).and_return(:ok)
|
||||
|
||||
expect { subject }.to change { repository.reload.migration_state }.to('pre_importing')
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'retrying the import' do
|
||||
it 'retries the import' do
|
||||
expect(repository).to receive(:migration_import).and_return(:ok)
|
||||
|
||||
expect { subject }.to change { repository.reload.migration_state }.to('importing')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when migration_state is not aborted' do
|
||||
it_behaves_like 'no action'
|
||||
end
|
||||
|
||||
context 'when migration_state is aborted' do
|
||||
before do
|
||||
repository.abort_import
|
||||
|
||||
allow(repository.gitlab_api_client)
|
||||
.to receive(:import_status).with(repository.path).and_return(client_response)
|
||||
end
|
||||
|
||||
context 'native response' do
|
||||
let(:client_response) { 'native' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject }.to raise_error(described_class::NativeImportError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'import_in_progress response' do
|
||||
let(:client_response) { 'import_in_progress' }
|
||||
|
||||
it_behaves_like 'no action'
|
||||
end
|
||||
|
||||
context 'import_complete response' do
|
||||
let(:client_response) { 'import_complete' }
|
||||
|
||||
it 'finishes the import' do
|
||||
expect { subject }.to change { repository.reload.migration_state }.to('import_done')
|
||||
end
|
||||
end
|
||||
|
||||
context 'import_failed response' do
|
||||
let(:client_response) { 'import_failed' }
|
||||
|
||||
it_behaves_like 'retrying the import'
|
||||
end
|
||||
|
||||
context 'pre_import_in_progress response' do
|
||||
let(:client_response) { 'pre_import_in_progress' }
|
||||
|
||||
it_behaves_like 'no action'
|
||||
end
|
||||
|
||||
context 'pre_import_complete response' do
|
||||
let(:client_response) { 'pre_import_complete' }
|
||||
|
||||
it 'finishes the pre_import and starts the import' do
|
||||
expect(repository).to receive(:finish_pre_import).and_call_original
|
||||
expect(repository).to receive(:migration_import).and_return(:ok)
|
||||
|
||||
expect { subject }.to change { repository.reload.migration_state }.to('importing')
|
||||
end
|
||||
end
|
||||
|
||||
context 'pre_import_failed response' do
|
||||
let(:client_response) { 'pre_import_failed' }
|
||||
|
||||
it_behaves_like 'retrying the pre_import'
|
||||
end
|
||||
|
||||
context 'error response' do
|
||||
let(:client_response) { 'error' }
|
||||
|
||||
context 'migration_pre_import_done_at is NULL' do
|
||||
it_behaves_like 'retrying the pre_import'
|
||||
end
|
||||
|
||||
context 'migration_pre_import_done_at is not NULL' do
|
||||
before do
|
||||
repository.update_columns(
|
||||
migration_pre_import_started_at: 5.minutes.ago,
|
||||
migration_pre_import_done_at: Time.zone.now
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'retrying the import'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tag' do
|
||||
|
|
82
spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb
Normal file
82
spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'fast_spec_helper'
|
||||
|
||||
require_relative '../../../../rubocop/cop/gitlab/event_store_subscriber'
|
||||
|
||||
RSpec.describe RuboCop::Cop::Gitlab::EventStoreSubscriber do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context 'when an event store subscriber overrides #perform' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<~WORKER)
|
||||
class SomeWorker
|
||||
include Gitlab::EventStore::Subscriber
|
||||
|
||||
def perform(*args)
|
||||
^^^^^^^^^^^^^^^^^^ Do not override `perform` in a `Gitlab::EventStore::Subscriber`.
|
||||
end
|
||||
|
||||
def handle_event(event); end
|
||||
end
|
||||
WORKER
|
||||
end
|
||||
end
|
||||
|
||||
context 'when an event store subscriber does not override #perform' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<~WORKER)
|
||||
class SomeWorker
|
||||
include Gitlab::EventStore::Subscriber
|
||||
|
||||
def handle_event(event); end
|
||||
end
|
||||
WORKER
|
||||
end
|
||||
end
|
||||
|
||||
context 'when an event store subscriber does not implement #handle_event' do
|
||||
it 'registers an offense' do
|
||||
expect_offense(<<~WORKER)
|
||||
class SomeWorker
|
||||
include Gitlab::EventStore::Subscriber
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A `Gitlab::EventStore::Subscriber` must implement `#handle_event(event)`.
|
||||
end
|
||||
WORKER
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a Sidekiq worker overrides #perform' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<~WORKER)
|
||||
class SomeWorker
|
||||
include ApplicationWorker
|
||||
|
||||
def perform(*args); end
|
||||
end
|
||||
WORKER
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a Sidekiq worker implements #handle_event' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<~WORKER)
|
||||
class SomeWorker
|
||||
include ApplicationWorker
|
||||
|
||||
def handle_event(event); end
|
||||
end
|
||||
WORKER
|
||||
end
|
||||
end
|
||||
|
||||
context 'a non worker class' do
|
||||
it 'does not register an offense' do
|
||||
expect_no_offenses(<<~MODEL)
|
||||
class Model < ApplicationRecord
|
||||
include ActiveSupport::Concern
|
||||
end
|
||||
MODEL
|
||||
end
|
||||
end
|
||||
end
|
9
spec/support/cross_database_modification.rb
Normal file
9
spec/support/cross_database_modification.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.after do |example|
|
||||
[::ApplicationRecord, ::Ci::ApplicationRecord].each do |base_class|
|
||||
base_class.gitlab_transactions_stack.clear if base_class.respond_to?(:gitlab_transactions_stack)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -113,6 +113,7 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures
|
|||
allow(worker).to receive(:next_aborted_repository) do
|
||||
next_aborted_repository = method.call
|
||||
allow(next_aborted_repository).to receive(:migration_import).and_return(:ok)
|
||||
allow(next_aborted_repository.gitlab_api_client).to receive(:import_status).and_return('import_failed')
|
||||
next_aborted_repository
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue