Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-07-22 18:08:29 +00:00
parent 684f0a68d5
commit d81dc2a54e
62 changed files with 416 additions and 222 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 B

View File

@ -9,7 +9,7 @@ module FindSnippet
# rubocop:disable CodeReuse/ActiveRecord
def snippet
strong_memoize(:snippet) do
snippet_klass.inc_relations_for_view.find_by(id: snippet_id)
snippet_klass.inc_relations_for_view.find_by(snippet_find_params)
end
end
# rubocop:enable CodeReuse/ActiveRecord
@ -21,4 +21,8 @@ module FindSnippet
def snippet_id
params[:id]
end
def snippet_find_params
{ id: snippet_id }
end
end

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
class Projects::SnippetsController < Projects::Snippets::ApplicationController
extend ::Gitlab::Utils::Override
include SnippetsActions
include ToggleAwardEmoji
include SpammableActions
@ -45,4 +46,9 @@ class Projects::SnippetsController < Projects::Snippets::ApplicationController
def spammable_path
project_snippet_path(@project, @snippet)
end
override :snippet_find_params
def snippet_find_params
super.merge(project_id: project.id)
end
end

View File

@ -32,7 +32,10 @@
- if page_canonical_link
%link{ rel: 'canonical', href: page_canonical_link }
= preload_link_tag(path_to_stylesheet('application_utilities'))
- if user_application_theme == 'gl-dark'
= preload_link_tag(path_to_stylesheet('application_utilities_dark'))
- else
= preload_link_tag(path_to_stylesheet('application_utilities'))
= yield :prefetch_asset_tags
= favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png'
@ -40,10 +43,12 @@
= render 'layouts/startup_css', { startup_filename: local_assigns.fetch(:startup_filename, nil) }
- if user_application_theme == 'gl-dark'
= stylesheet_link_tag_defer "application_dark"
= yield :page_specific_styles
= stylesheet_link_tag_defer "application_utilities_dark"
- else
= stylesheet_link_tag_defer "application"
= yield :page_specific_styles
= stylesheet_link_tag_defer 'application_utilities'
= yield :page_specific_styles
= stylesheet_link_tag_defer 'application_utilities'
= stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
= stylesheet_link_tag "test_environment", media: "all" if Rails.env.test?

View File

@ -0,0 +1,8 @@
---
name: import_redis_increment_by
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65773
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336226
milestone: '14.1'
type: development
group: group::import
default_enabled: false

View File

@ -0,0 +1,15 @@
const fs = require('fs');
const path = require('path');
const IS_EE = require('./is_ee_env');
const ROOT_PATH = path.resolve(__dirname, '../..');
// The `FOSS_ONLY` is always `string` or `nil`
// Thus the nil or empty string will result
// in using default value: false
//
// The behavior needs to be synchronised with
// lib/gitlab.rb: Gitlab.jh?
// Since IS_EE already satisifies the conditions of not being a FOSS_ONLY.
// const isFossOnly = JSON.parse(process.env.FOSS_ONLY || 'false');
module.exports = IS_EE && fs.existsSync(path.join(ROOT_PATH, 'jh'));

View File

@ -20,6 +20,7 @@ const WEBPACK_VERSION = require('webpack/package.json').version;
const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler');
const IS_EE = require('./helpers/is_ee_env');
const IS_JH = require('./helpers/is_jh_env');
const vendorDllHash = require('./helpers/vendor_dll_hash');
const MonacoWebpackPlugin = require('./plugins/monaco_webpack');
@ -97,6 +98,14 @@ function generateEntries() {
watchAutoEntries.push(path.join(ROOT_PATH, 'ee/app/assets/javascripts/pages/'));
}
if (IS_JH) {
const eePageEntries = glob.sync('pages/**/index.js', {
cwd: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
});
eePageEntries.forEach((entryPath) => generateAutoEntries(entryPath, 'jh'));
watchAutoEntries.push(path.join(ROOT_PATH, 'jh/app/assets/javascripts/pages/'));
}
const autoEntryKeys = Object.keys(autoEntriesMap);
autoEntriesCount = autoEntryKeys.length;
@ -168,6 +177,16 @@ if (IS_EE) {
});
}
if (IS_JH) {
Object.assign(alias, {
jh: path.join(ROOT_PATH, 'jh/app/assets/javascripts'),
jh_icons: path.join(ROOT_PATH, 'jh/app/views/shared/icons'),
jh_images: path.join(ROOT_PATH, 'jh/app/assets/images'),
jh_spec: path.join(ROOT_PATH, 'jh/spec/javascripts'),
jh_jest: path.join(ROOT_PATH, 'jh/spec/frontend'),
});
}
if (!IS_PRODUCTION) {
const fixtureDir = IS_EE ? 'fixtures-ee' : 'fixtures';

View File

@ -892,26 +892,6 @@ understand the implications.
WARNING:
This is a destructive operation.
When you run `registry-garbage-collect` with the -m flag, garbage collection unlinks manifests that
are part of a multi-arch manifest, unless they're tagged in the same repository.
See [this issue](https://gitlab.com/gitlab-org/container-registry/-/issues/149) for details.
To work around this issue, instead of:
```plaintext
myrepo/multiarchmanifest:latest
myrepo/manifest/amd-64:latest
myrepo/manifest/arm:latest
```
Use:
```plaintext
myrepo/multiarchmanifest:latest
myrepo/manifest:amd-64-latest
myrepo/manifest:arm-latest
```
The GitLab Container Registry follows the same default workflow as Docker Distribution:
retain untagged manifests and all layers, even ones that are not referenced directly. All content
can be accessed by using context addressable identifiers.

View File

@ -193,7 +193,7 @@ Combined with [protected branches](../../../user/project/protected_branches.md),
For the full list of options, see Vault's [Create Role documentation](https://www.vaultproject.io/api/auth/jwt#create-role).
WARNING:
Always restrict your roles to project or namespace by using one of the provided claims (e.g. `project_id` or `namespace_id`). Otherwise any JWT generated by this instance may be allowed to authenticate using this role.
Always restrict your roles to project or namespace by using one of the provided claims (for example, `project_id` or `namespace_id`). Otherwise any JWT generated by this instance may be allowed to authenticate using this role.
Now, configure the JWT Authentication method:

View File

@ -123,7 +123,7 @@ Therefore, for a production environment we use additional steps to ensure that a
Since this was a WordPress project, I gave real life code snippets. Some further ideas you can pursue:
- Having a slightly different script for the default branch allows you to deploy to a production server from that branch and to a stage server from any other branches.
- Instead of pushing it live, you can push it to WordPress official repository (with creating a SVN commit, etc.).
- Instead of pushing it live, you can push it to WordPress official repository.
- You could generate i18n text domains on the fly.
---

View File

@ -9,7 +9,7 @@ type: reference
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9788) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10. Requires GitLab Runner 11.10 and above.
GitLab provides a lot of great reporting tools for [merge requests](../user/project/merge_requests/index.md) - [Unit test reports](unit_test_reports.md), [code quality](../user/project/merge_requests/code_quality.md), performance tests, etc. While JUnit is a great open framework for tests that "pass" or "fail", it is also important to see other types of metrics from a given change.
GitLab provides a lot of great reporting tools for things like [merge requests](../user/project/merge_requests/index.md) - [Unit test reports](unit_test_reports.md), [code quality](../user/project/merge_requests/code_quality.md), and performance tests. While JUnit is a great open framework for tests that "pass" or "fail", it is also important to see other types of metrics from a given change.
You can configure your job to use custom Metrics Reports, and GitLab displays a report on the merge request so that it's easier and faster to identify changes without having to check the entire log.

View File

@ -153,8 +153,8 @@ is recreated and all pipelines restart.
### Merge request dropped from the merge train immediately
If a merge request is not mergeable (for example, it's a draft merge request, there is a merge
conflict, etc.), your merge request is dropped from the merge train automatically.
If a merge request is not mergeable (for example, it's a draft merge request or it has a merge
conflict), the merge train drops your merge request automatically.
In these cases, the reason for dropping the merge request is in the **system notes**.

View File

@ -13,7 +13,7 @@ environment (where the GitLab Runner runs).
The SSH keys can be useful when:
1. You want to checkout internal submodules
1. You want to download private packages using your package manager (e.g., Bundler)
1. You want to download private packages using your package manager (for example, Bundler)
1. You want to deploy your application to your own server, or, for example, Heroku
1. You want to execute SSH commands from the build environment to a remote server
1. You want to rsync files from the build environment to a remote server
@ -21,9 +21,9 @@ The SSH keys can be useful when:
If anything of the above rings a bell, then you most likely need an SSH key.
The most widely supported method is to inject an SSH key into your build
environment by extending your `.gitlab-ci.yml`, and it's a solution which works
environment by extending your `.gitlab-ci.yml`, and it's a solution that works
with any type of [executor](https://docs.gitlab.com/runner/executors/)
(Docker, shell, etc.).
(like Docker or shell, for example).
## How it works

View File

@ -113,7 +113,7 @@ Feature.disable(:variable_inside_variable, Project.find(<project id>))
- Supported: project/group variables, `.gitlab-ci.yml` variables, `config.toml` variables, and
variables from triggers, pipeline schedules, and manual pipelines.
- Not supported: variables defined inside of scripts (e.g., `export MY_VARIABLE="test"`).
- Not supported: variables defined inside of scripts (for example, `export MY_VARIABLE="test"`).
The runner uses Go's `os.Expand()` method for variable expansion. It means that it handles
only variables defined as `$variable` and `${variable}`. What's also important, is that
@ -132,7 +132,7 @@ use a different variables syntax.
Supported:
- The `script` may use all available variables that are default for the shell (e.g., `$PATH` which
- The `script` may use all available variables that are default for the shell (for example, `$PATH` which
should be present in all bash/sh shells) and all variables defined by GitLab CI/CD (project/group variables,
`.gitlab-ci.yml` variables, `config.toml` variables, and variables from triggers and pipeline schedules).
- The `script` may also use all variables defined in the lines before. So, for example, if you define

View File

@ -79,7 +79,7 @@ especially the case for small tables.
If a table is expected to grow in size and you expect your query has to filter
out a lot of rows you may want to consider adding an index. If the table size is
very small (e.g. less than `1,000` records) or any existing indexes filter out
very small (for example, fewer than `1,000` records) or any existing indexes filter out
enough rows you may _not_ want to add a new index.
## Maintenance Overhead

View File

@ -90,4 +90,4 @@ In addition, any system dependencies used in Omnibus packages or the Cloud Nativ
If the service component needs to be updated or released with the monthly GitLab release, then the component should be added to the [release tools automation](https://gitlab.com/gitlab-org/release-tools). This project is maintained by the [Delivery team](https://about.gitlab.com/handbook/engineering/infrastructure/team/delivery/). A list of the projects managed this way can be found in the [release tools project directory](https://about.gitlab.com/handbook/engineering/infrastructure/team/delivery/).
For example, during the monthly GitLab release, the desired version of Gitaly, GitLab Workhorse, GitLab Shell, etc., need to synchronized through the various release pipelines.
For example, during the monthly GitLab release, the desired version of Gitaly, GitLab Workhorse and GitLab Shell need to be synchronized through the various release pipelines.

View File

@ -148,7 +148,7 @@ to make this easier.
## Using HTTP status helpers
For non-200 HTTP responses, use the provided helpers in `lib/api/helpers.rb` to ensure correct behavior (`not_found!`, `no_content!` etc.). These `throw` inside Grape and abort the execution of your endpoint.
For non-200 HTTP responses, use the provided helpers in `lib/api/helpers.rb` to ensure correct behavior (like `not_found!` or `no_content!`). These `throw` inside Grape and abort the execution of your endpoint.
For `DELETE` requests, you should also generally use the `destroy_conditionally!` helper which by default returns a `204 No Content` response on success, or a `412 Precondition Failed` response if the given `If-Unmodified-Since` header is out of range. This helper calls `#destroy` on the passed resource, but you can also implement a custom deletion method by passing a block.

View File

@ -235,7 +235,7 @@ updating many rows in sequence.
To reduce database pressure you should instead use
`change_column_type_using_background_migration` or `rename_column_using_background_migration`
when migrating a column in a large table (e.g. `issues`). These methods work
when migrating a column in a large table (for example, `issues`). These methods work
similarly to the concurrent counterparts but uses background migration to spread
the work / load over a longer time period, without slowing down deployments.
@ -402,7 +402,7 @@ into errors. On the other hand, if we were to migrate after deploying the
application code we could run into the same problems.
If you merely need to correct some invalid data, then a post-deployment
migration is usually enough. If you need to change the format of data (e.g. from
migration is usually enough. If you need to change the format of data (for example, from
JSON to something else) it's typically best to add a new column for the new data
format, and have the application use that. In such a case the procedure would
be:

View File

@ -31,7 +31,7 @@ Some examples where background migrations can be useful:
- Migrating events from one table to multiple separate tables.
- Populating one column based on JSON stored in another column.
- Migrating data that depends on the output of external services (e.g. an API).
- Migrating data that depends on the output of external services (for example, an API).
NOTE:
If the background migration is part of an important upgrade, make sure it's announced
@ -40,7 +40,7 @@ into this category.
## Isolation
Background migrations must be isolated and can not use application code (e.g.
Background migrations must be isolated and can not use application code (for example,
models defined in `app/models`). Since these migrations can take a long time to
run it's possible for new versions to be deployed while they are still running.
@ -157,7 +157,7 @@ Because background migrations can take a long time you can't immediately clean
things up after scheduling them. For example, you can't drop a column that's
used in the migration process as this would cause jobs to fail. This means that
you'll need to add a separate _post deployment_ migration in a future release
that finishes any remaining jobs before cleaning things up (e.g. removing a
that finishes any remaining jobs before cleaning things up (for example, removing a
column).
As an example, say you want to migrate the data from column `foo` (containing a
@ -167,7 +167,7 @@ roughly be as follows:
1. Release A:
1. Create a migration class that perform the migration for a row with a given ID.
1. Deploy the code for this release, this should include some code that will
schedule jobs for newly created data (e.g. using an `after_create` hook).
schedule jobs for newly created data (for example, using an `after_create` hook).
1. Schedule jobs for all existing rows in a post-deployment migration. It's
possible some newly created rows may be scheduled twice so your migration
should take care of this.
@ -178,7 +178,7 @@ roughly be as follows:
`BackgroundMigrationHelpers` to ensure no jobs remain. This helper will:
1. Use `Gitlab::BackgroundMigration.steal` to process any remaining
jobs in Sidekiq.
1. Reschedule the migration to be run directly (i.e. not through Sidekiq)
1. Reschedule the migration to be run directly (that is, not through Sidekiq)
on any rows that weren't migrated by Sidekiq. This can happen if, for
instance, Sidekiq received a SIGKILL, or if a particular batch failed
enough times to be marked as dead.

View File

@ -29,7 +29,7 @@ trigger.
## Specifying versions of components
If you want to create a package from a specific branch, commit or tag of any of
the GitLab components (like GitLab Workhorse, Gitaly, GitLab Pages, etc.), you
the GitLab components (like GitLab Workhorse, Gitaly, or GitLab Pages), you
can specify the branch name, commit SHA or tag in the component's respective
`*_VERSION` file. For example, if you want to build a package that uses the
branch `0-1-stable`, modify the content of `GITALY_SERVER_VERSION` to

View File

@ -45,7 +45,7 @@ processing it, and returns any syntax or semantic errors. The `YAML Processor` c
[all the keywords](../../ci/yaml/index.md) available to structure a pipeline.
The `CreatePipelineService` receives the abstract data structure returned by the `YAML Processor`,
which then converts it to persisted models (pipeline, stages, jobs, etc.). After that, the pipeline is ready
which then converts it to persisted models (like pipeline, stages, and jobs). After that, the pipeline is ready
to be processed. Processing a pipeline means running the jobs in order of execution (stage or DAG)
until either one of the following:
@ -77,7 +77,7 @@ that need to be stored. Also, a job may depend on artifacts from previous jobs i
case the runner downloads them using a dedicated API endpoint.
Artifacts are stored in object storage, while metadata is kept in the database. An important example of artifacts
are reports (JUnit, SAST, DAST, etc.) which are parsed and rendered in the merge request.
are reports (like JUnit, SAST, and DAST) which are parsed and rendered in the merge request.
Job status transitions are not all automated. A user may run [manual jobs](../../ci/yaml/index.md#whenmanual), cancel a pipeline, retry
specific failed jobs or the entire pipeline. Anything that

View File

@ -52,8 +52,8 @@ When self-identifying as a domain expert, it is recommended to assign the MR cha
We make the following assumption with regards to automatically being considered a domain expert:
- Team members working in a specific stage/group (e.g. create: source code) are considered domain experts for that area of the app they work on
- Team members working on a specific feature (e.g. search) are considered domain experts for that feature
- Team members working in a specific stage/group (for example, create: source code) are considered domain experts for that area of the app they work on
- Team members working on a specific feature (for example, search) are considered domain experts for that feature
We default to assigning reviews to team members with domain expertise.
When a suitable [domain expert](#domain-experts) isn't available, you can choose any team member to review the MR, or simply follow the [Reviewer roulette](#reviewer-roulette) recommendation.

View File

@ -12,7 +12,7 @@ GitLab community members and their privileges/responsibilities.
|-------|------------------|--------------|
| Maintainer | Accepts merge requests on several GitLab projects | Added to the [team page](https://about.gitlab.com/company/team/). An expert on code reviews and knows the product/codebase |
| Reviewer | Performs code reviews on MRs | Added to the [team page](https://about.gitlab.com/company/team/) |
| Developer |Has access to GitLab internal infrastructure & issues (e.g. HR-related) | GitLab employee or a Core Team member (with an NDA) |
| Developer |Has access to GitLab internal infrastructure & issues (for example, HR-related) | GitLab employee or a Core Team member (with an NDA) |
| Contributor | Can make contributions to all GitLab public projects | Have a GitLab.com account |
[List of current reviewers/maintainers](https://about.gitlab.com/handbook/engineering/projects/#gitlab-ce).

View File

@ -191,7 +191,7 @@ If you are not sure who to mention, the reviewer will do this for you early in t
A "breaking change" is any change that requires users to make a corresponding change to their code, settings, or workflow. "Users" might be humans, API clients, or even code classes that "use" another class. Examples of breaking changes include:
- Removing a user-facing feature without a replacement/workaround.
- Changing the definition of an existing API (by re-naming query parameters, changing routes, etc.).
- Changing the definition of an existing API (by doing things like re-naming query parameters or changing routes).
- Removing a public method from a code class.
A breaking change can be considered "major" if it affects many users, or represents a significant change in behavior.

View File

@ -47,11 +47,11 @@ scheduling into milestones. Labeling is a task for everyone. (For some projects,
Most issues will have labels for at least one of the following:
- Type: `~feature`, `~bug`, `~tooling`, `~documentation`, etc.
- Stage: `~"devops::plan"`, `~"devops::create"`, etc.
- Group: `~"group::source code"`, `~"group::knowledge"`, `~"group::editor"`, etc.
- Category: `~"Category:Code Analytics"`, `~"Category:DevOps Reports"`, `~"Category:Templates"`, etc.
- Feature: `~wiki`, `~ldap`, `~api`, `~issues`, `~"merge requests"`, etc.
- Type. For example: `~feature`, `~bug`, `~tooling`, or `~documentation`.
- Stage. For example: `~"devops::plan"` or `~"devops::create"`.
- Group. For example: `~"group::source code"`, `~"group::knowledge"`, or `~"group::editor"`.
- Category. For example: `~"Category:Code Analytics"`, `~"Category:DevOps Reports"`, or `~"Category:Templates"`.
- Feature. For example: `~wiki`, `~ldap`, `~api`, `~issues`, or `~"merge requests"`.
- Department: `~UX`, `~Quality`
- Team: `~"Technical Writing"`, `~Delivery`
- Specialization: `~frontend`, `~backend`, `~documentation`
@ -201,7 +201,7 @@ If you are an expert in a particular area, it makes it easier to find issues to
work on. You can also subscribe to those labels to receive an email each time an
issue is labeled with a feature label corresponding to your expertise.
Examples of feature labels are `~wiki`, `~ldap`, `~api`, `~issues`, `~"merge requests"` etc.
Examples of feature labels are `~wiki`, `~ldap`, `~api`, `~issues`, and `~"merge requests"`.
#### Naming and color convention
@ -223,7 +223,7 @@ The current department labels are:
### Team labels
**Important**: Most of the historical team labels (e.g. Manage, Plan etc.) are
**Important**: Most of the historical team labels (like Manage or Plan) are
now deprecated in favor of [Group labels](#group-labels) and [Stage labels](#stage-labels).
Team labels specify what team is responsible for this issue.

View File

@ -23,8 +23,8 @@ wireframes of the proposed feature if it will also change the UI.
Merge requests should be submitted to the appropriate project at GitLab.com, for example
[GitLab](https://gitlab.com/gitlab-org/gitlab/-/merge_requests),
[GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests),
[Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests), etc.
[GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests), or
[Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests).
If you are new to GitLab development (or web development in general), see the
[how to contribute](index.md#how-to-contribute) section to get started with
@ -69,7 +69,7 @@ request is as follows:
request addresses. Referenced issues do not [close automatically](../../user/project/issues/managing_issues.md#closing-issues-automatically).
You must close them manually once the merge request is merged.
1. The MR must include *Before* and *After* screenshots if UI changes are made.
1. Include any steps or setup required to ensure reviewers can view the changes you've made (e.g. include any information about feature flags).
1. Include any steps or setup required to ensure reviewers can view the changes you've made (for example, include any information about feature flags).
1. If you're allowed to, set a relevant milestone and [labels](issue_workflow.md).
1. UI changes should use available components from the GitLab Design System,
[Pajamas](https://design.gitlab.com/).
@ -204,7 +204,7 @@ the contribution acceptance criteria below:
only one working on your feature branch, otherwise merge `main`.
1. Only one specific issue is fixed or one specific feature is implemented. Do not
combine things; send separate merge requests for each issue or feature.
1. Migrations should do only one thing (e.g., create a table, move data to a new
1. Migrations should do only one thing (for example, create a table, move data to a new
table, or remove an old table) to aid retrying on failure.
1. Contains functionality that other users will benefit from.
1. Doesn't add configuration options or settings options since they complicate making
@ -214,7 +214,7 @@ the contribution acceptance criteria below:
- Check for N+1 queries via the SQL log or [`QueryRecorder`](../merge_request_performance_guidelines.md).
- Avoid repeated access of the file system.
- Use [polling with ETag caching](../polling.md) if needed to support real-time features.
1. If the merge request adds any new libraries (gems, JavaScript libraries, etc.),
1. If the merge request adds any new libraries (like gems or JavaScript libraries),
they should conform to our [Licensing guidelines](../licensing.md). See those
instructions for help if the "license-finder" test fails with a
`Dependencies that need approval` error. Also, make the reviewer aware of the new
@ -272,7 +272,7 @@ request:
We allow engineering time to fix small problems (with or without an
issue) that are incremental improvements, such as:
1. Unprioritized bug fixes (e.g. [Banner alerting of project move is
1. Unprioritized bug fixes (for example, [Banner alerting of project move is
showing up everywhere](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18985))
1. Documentation improvements
1. Rubocop or Code Quality improvements

View File

@ -73,9 +73,9 @@ end
This works as-is, however, it has a couple of downside that:
- Someone could define a key/value pair in EE that is **conflicted** with a value defined in FOSS.
e.g. Define `activity_limit_exceeded: 1` in `EE::Enums::Pipeline`.
For example, define `activity_limit_exceeded: 1` in `EE::Enums::Pipeline`.
- When it happens, the feature works totally different.
e.g. We cannot figure out `failure_reason` is either `config_error` or `activity_limit_exceeded`.
For example, we cannot figure out `failure_reason` is either `config_error` or `activity_limit_exceeded`.
- When it happens, we have to ship a database migration to fix the data integrity,
which might be impossible if you cannot recover the original value.
@ -98,7 +98,7 @@ end
This looks working as a workaround, however, this approach has some downsides that:
- Features could move from EE to FOSS or vice versa. Therefore, the offset might be mixed between FOSS and EE in the future.
e.g. When you move `activity_limit_exceeded` to FOSS, you'll see `{ unknown_failure: 0, config_error: 1, activity_limit_exceeded: 1_000 }`.
For example, when you move `activity_limit_exceeded` to FOSS, you'll see `{ unknown_failure: 0, config_error: 1, activity_limit_exceeded: 1_000 }`.
- The integer column for the `enum` is likely created [as `SMALLINT`](#creating-enums).
Therefore, you need to be careful of that the offset doesn't exceed the maximum value of 2 bytes integer.

View File

@ -58,7 +58,7 @@ different releases:
1. Release `N.M` (current release)
- Ensure the constraint is enforced at the application level (i.e. add a model validation).
- Ensure the constraint is enforced at the application level (that is, add a model validation).
- Add a post-deployment migration to add the `NOT NULL` constraint with `validate: false`.
- Add a post-deployment migration to fix the existing records.

View File

@ -128,7 +128,7 @@ test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slac
- Write the raw SQL in the MR description. Preferably formatted
nicely with [pgFormatter](https://sqlformat.darold.net) or
[paste.depesz.com](https://paste.depesz.com) and using regular quotes
(e.g. `"projects"."id"`) and avoiding smart quotes (e.g. `“projects”.“id”`).
(for example, `"projects"."id"`) and avoiding smart quotes (for example, `“projects”.“id”`).
- In case of queries generated dynamically by using parameters, there should be one raw SQL query for each variation.
For example, a finder for issues that may take as a parameter an optional filter on projects,

View File

@ -21,8 +21,8 @@ Instead of deleting we can opt for disabling the migration.
Migrations can be disabled if:
- They caused a timeout or general issue on GitLab.com.
- They are obsoleted, e.g. changes are not necessary due to a feature change.
- Migration is a data migration only, i.e. the migration does not change the database schema.
- They are obsoleted, for example, changes are not necessary due to a feature change.
- Migration is a data migration only, that is, the migration does not change the database schema.
## How to disable a data migration?

View File

@ -72,7 +72,7 @@ could make them shallow and more coupled with other contexts.
Bounded contexts (or top-level namespaces) can be seen as macro-components in the overall app.
Good bounded contexts should be [deep](https://medium.com/@nakabonne/depth-of-module-f62dac3c2fdb)
so consider having nested namespaces to further break down complex parts of the domain.
E.g. `Ci::Config::`.
For example, `Ci::Config::`.
For example, instead of having separate and granular bounded contexts like: `ContainerScanning::`,
`ContainerHostSecurity::`, `ContainerNetworkSecurity::`, we could have:

View File

@ -317,7 +317,7 @@ Use sentence case. For example:
When referring to specific user interface text, like a button label or menu
item, use the same capitalization that's displayed in the user interface.
Standards for this content are listed in the [Pajamas Design System Content section](https://design.gitlab.com/content/punctuation/)
and typically match what's called for in this Documentation Style Guide.
and typically match what's mentioned in this Documentation Style Guide.
If you think the user interface text contains style mistakes,
create an issue or an MR to propose a change to the user interface text.
@ -768,7 +768,7 @@ Valid for Markdown content only, not for front matter entries:
"This sentence 'quotes' something in a quote".
For other punctuation rules, refer to the
[GitLab UX guide](https://design.gitlab.com/content/punctuation/).
[Pajamas Design System Punctuation section](https://design.gitlab.com/content/punctuation/).
## Headings

View File

@ -174,10 +174,10 @@ There are a few gotchas with it:
implementation, you should refactor the CE method and split it in
smaller methods. Or create a "hook" method that is empty in CE,
and with the EE-specific implementation in EE.
- when the original implementation contains a guard clause (e.g.
- when the original implementation contains a guard clause (for example,
`return unless condition`), we cannot easily extend the behavior by
overriding the method, because we can't know when the overridden method
(i.e. calling `super` in the overriding method) would want to stop early.
(that is, calling `super` in the overriding method) would want to stop early.
In this case, we shouldn't just override it, but update the original method
to make it call the other method we want to extend, like a [template method
pattern](https://en.wikipedia.org/wiki/Template_method_pattern).
@ -522,10 +522,10 @@ Resolving an EE template path that is relative to the CE view path doesn't work.
For `render` and `render_if_exists`, they search for the EE partial first,
and then CE partial. They would only render a particular partial, not all
partials with the same name. We could take the advantage of this, so that
the same partial path (e.g. `shared/issuable/form/default_templates`) could
be referring to the CE partial in CE (i.e.
the same partial path (for example, `shared/issuable/form/default_templates`) could
be referring to the CE partial in CE (that is,
`app/views/shared/issuable/form/_default_templates.html.haml`), while EE
partial in EE (i.e.
partial in EE (that is,
`ee/app/views/shared/issuable/form/_default_templates.html.haml`). This way,
we could show different things between CE and EE.
@ -549,8 +549,8 @@ In the above example, we can't use
`render 'shared/issuable/form/default_templates'` because it would find the
same EE partial, causing infinite recursion. Instead, we could use `render_ce`
so it ignores any partials in `ee/` and then it would render the CE partial
(i.e. `app/views/shared/issuable/form/_default_templates.html.haml`)
for the same path (i.e. `shared/issuable/form/default_templates`). This way
(that is, `app/views/shared/issuable/form/_default_templates.html.haml`)
for the same path (that is, `shared/issuable/form/default_templates`). This way
we could easily wrap around the CE partial.
### Code in `lib/`
@ -1107,7 +1107,7 @@ If a component you're adding styles for is limited to EE, it is better to have a
separate SCSS file in an appropriate directory within `app/assets/stylesheets`.
In some cases, this is not entirely possible or creating dedicated SCSS file is an overkill,
e.g. a text style of some component is different for EE. In such cases,
for example, a text style of some component is different for EE. In such cases,
styles are usually kept in a stylesheet that is common for both CE and EE, and it is wise
to isolate such ruleset from rest of CE rules (along with adding comment describing the same)
to avoid conflicts during CE to EE merge.

View File

@ -142,13 +142,13 @@ forwarded to both indices. Once the new index is ready, an admin can
mark it active, which will direct all searches to it, and remove the old
index.
This is also helpful for migrating to new servers, e.g. moving to/from AWS.
This is also helpful for migrating to new servers, for example, moving to/from AWS.
Currently we are on the process of migrating to this new design. Everything is hardwired to work with one single version for now.
### Architecture
The traditional setup, provided by `elasticsearch-rails`, is to communicate through its internal proxy classes. Developers would write model-specific logic in a module for the model to include in (e.g. `SnippetsSearch`). The `__elasticsearch__` methods would return a proxy object, e.g.:
The traditional setup, provided by `elasticsearch-rails`, is to communicate through its internal proxy classes. Developers would write model-specific logic in a module for the model to include in (for example, `SnippetsSearch`). The `__elasticsearch__` methods would return a proxy object, for example:
- `Issue.__elasticsearch__` returns an instance of `Elasticsearch::Model::Proxy::ClassMethodsProxy`
- `Issue.first.__elasticsearch__` returns an instance of `Elasticsearch::Model::Proxy::InstanceMethodsProxy`.
@ -171,7 +171,7 @@ The global configurations per version are now in the `Elastic::(Version)::Config
NOTE:
This is not applicable yet as multiple indices functionality is not fully implemented.
Folders like `ee/lib/elastic/v12p1` contain snapshots of search logic from different versions. To keep a continuous Git history, the latest version lives under `ee/lib/elastic/latest`, but its classes are aliased under an actual version (e.g. `ee/lib/elastic/v12p3`). When referencing these classes, never use the `Latest` namespace directly, but use the actual version (e.g. `V12p3`).
Folders like `ee/lib/elastic/v12p1` contain snapshots of search logic from different versions. To keep a continuous Git history, the latest version lives under `ee/lib/elastic/latest`, but its classes are aliased under an actual version (for example, `ee/lib/elastic/v12p3`). When referencing these classes, never use the `Latest` namespace directly, but use the actual version (for example, `V12p3`).
The version name basically follows the GitLab release version. If setting is changed in 12.3, we will create a new namespace called `V12p3` (p stands for "point"). Raise an issue if there is a need to name a version differently.
@ -254,7 +254,7 @@ class BatchedMigrationName < Elastic::Migration
throttle_delay 10.minutes
pause_indexing!
space_requirements!
# ...
end
```

View File

@ -59,7 +59,7 @@ Shared Global Object's solve the problem of making something globally accessible
could be appropriate:
- When a responsibility is truly global and should be referenced across the application
(e.g., an application-wide Event Bus).
(for example, an application-wide Event Bus).
Even in these scenarios, please consider avoiding the Shared Global Object pattern because the
side-effects can be notoriously difficult to reason with.
@ -136,8 +136,8 @@ many problems with a module that exports utility functions.
Singletons solve the problem of enforcing there to be only 1 instance of a thing. It's possible
that a Singleton could be appropriate in the following rare cases:
- We need to manage some resource that **MUST** have just 1 instance (i.e. some hardware restriction).
- There is a real [cross-cutting concern](https://en.wikipedia.org/wiki/Cross-cutting_concern) (e.g., logging) and a Singleton provides the simplest API.
- We need to manage some resource that **MUST** have just 1 instance (that is, some hardware restriction).
- There is a real [cross-cutting concern](https://en.wikipedia.org/wiki/Cross-cutting_concern) (for example, logging) and a Singleton provides the simplest API.
Even in these scenarios, please consider avoiding the Singleton pattern.
@ -174,7 +174,7 @@ export const fuzzify = (id) => { /* ... */ };
#### Dependency Injection
[Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) is an approach which breaks
coupling by declaring a module's dependencies to be injected from outside the module (e.g., through constructor parameters, a bona-fide Dependency Injection framework, and even Vue's `provide/inject`).
coupling by declaring a module's dependencies to be injected from outside the module (for example, through constructor parameters, a bona-fide Dependency Injection framework, and even Vue's `provide/inject`).
```javascript
// bad - Vue component coupled to Singleton

View File

@ -123,6 +123,27 @@ them before continuing the rebase.
To learn more, check Git's documentation on [rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)
and [rebasing strategies](https://git-scm.com/book/en/v2/Git-Branching-Rebasing).
#### Rebase from the GitLab UI
You can rebase your feature branch directly from the merge request through a
[quick action](../../user/project/quick_actions.md#issues-merge-requests-and-epics),
if all of these conditions are met:
- No [merge conflicts](#merge-conflicts) exist for your feature branch.
- You have the **Developer** role for the source project. This role grants you
permission to push to the source branch for the source project.
- If the merge request is in a fork, the fork must allow commits
[from members of the upstream project](../../user/project/merge_requests/allow_collaboration.md).
To rebase from the UI:
1. Go to your merge request.
1. Type `/rebase` in a comment.
1. Select **Comment**.
GitLab schedules a rebase of the feature branch against the default branch and
executes it as soon as possible.
### Interactive rebase
You can use interactive rebase to modify commits. For example, amend a commit

View File

@ -273,9 +273,10 @@ migrating data. Background migrations are only added in the monthly releases.
Certain major/minor releases may require a set of background migrations to be
finished. To guarantee this, such a release processes any remaining jobs
before continuing the upgrading procedure. While this doesn't require downtime
(if the above conditions are met) we recommend users to keep at least 1 week
between upgrading major/minor releases, allowing the background migrations to
finish. The time necessary to complete these migrations can be reduced by
(if the above conditions are met) we require that you [wait for background
migrations to complete](#checking-for-background-migrations-before-upgrading)
between each major/minor release upgrade.
The time necessary to complete these migrations can be reduced by
increasing the number of Sidekiq workers that can process jobs in the
`background_migration` queue. To see the size of this queue,
[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -186,10 +186,9 @@ Some filters can be added multiple times. These include but are not limited to a
## To-Do List
Your [To-Do List](../todos.md#gitlab-to-do-list) can be searched by "to do" and "done".
You can [filter](../todos.md#filtering-your-to-do-list) them per project,
author, type, and action. Also, you can sort them by
[**Label priority**](../../user/project/labels.md#label-priority),
You can search your [To-Do List](../todos.md) by "to do" and "done".
You can filter to-do items per project, author, type, and action.
Also, you can sort them by [**Label priority**](../../user/project/labels.md#label-priority),
**Last created**, and **Oldest created**.
## Projects

View File

@ -5,47 +5,37 @@ group: Project Management
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
---
# GitLab To-Do List **(FREE)**
# To-Do List **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/2817) in GitLab 8.5.
When you sign in to GitLab, you normally want to determine where you should
spend your time. This can include taking an action, or keeping track of things
(without having to read lots of email notifications). Because GitLab is where you
do your work, being able to get started quickly is important.
Your *To-Do List* is a chronological list of items waiting for your input.
The items are known as *to-do items*.
Your *To-Do List* offers a chronological list of items waiting for your input
(known as *to-do items*) in a single dashboard.
The To-Do List supports tracking [actions](#what-triggers-a-to-do-item) related to
the following:
You can use the To-Do List to track [actions](#actions-that-create-to-do-items) related to:
- [Issues](project/issues/index.md)
- [Merge requests](project/merge_requests/index.md)
- [Epics](group/epics/index.md)
- [Designs](project/issues/design_management.md)
![to-do list with items to check on](img/todos_index_v13_11.png)
## Access the To-Do List
You can access your To-Do List by clicking the To-Do List icon (**{task-done}**)
next to the search bar in the top navigation. If the to-do item count is:
To access your To-Do List:
- *Less than 100*, the number in blue is the number of to-do items.
- *100 or more*, the number displays as 99+. The exact number displays in the
To-Do List.
On the top bar, in the top right, select To-Do List (**{task-done}**).
## What triggers a to-do item
## Actions that create to-do items
A to-do item appears on your To-Do List when:
Many to-do items are created automatically.
A to-do item is added to your To-Do List when:
- An issue or merge request is assigned to you.
- You're `@mentioned` in the description or comment of an issue or merge request
(or epic).
- You are `@mentioned` in a comment on a:
- Commit
- Design
- The CI/CD pipeline for your merge request failed.
- An open merge request becomes unmergeable due to conflict, and one of the
- You're `@mentioned` in the description or comment of an issue, merge request,
or epic.
- You are `@mentioned` in a comment on a commit or design.
- The CI/CD pipeline for your merge request fails.
- An open merge request cannot be merged due to conflict, and one of the
following is true:
- You're the author.
- You're the user that set the merge request to automatically merge after a
@ -55,24 +45,32 @@ A to-do item appears on your To-Do List when:
[merge train](../ci/pipelines/merge_trains.md),
and you're the user that added it.
When several trigger actions occur for the same user on the same object (for
example, an issue), GitLab displays only the first action as a single to-do
item.
When several actions occur for the same user on the same object,
GitLab displays the first action as a single to-do item.
To-do item triggers aren't affected by [GitLab notification email settings](profile/notifications.md).
To-do items aren't affected by [GitLab notification email settings](profile/notifications.md).
NOTE:
When a user no longer has access to a resource related to a to-do item (such as
an issue, merge request, epic, project, or group), for security reasons GitLab
deletes any related to-do items within the next hour. Deletion is delayed to
prevent data loss, in the case where a user's access is accidentally revoked.
## Create a to-do item
### Directly addressing a to-do item
You can manually add an item to your To-Do List.
1. Go to your:
- [Issue](project/issues/index.md)
- [Merge request](project/merge_requests/index.md)
- [Epic](group/epics/index.md)
- [Design](project/issues/design_management.md)
1. On the right sidebar, at the top, select **Add a to do**.
![Adding a to-do item from the issuable sidebar](img/todos_add_todo_sidebar_v14_1.png)
## Create a to-do item by directly addressing someone
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7926) in GitLab 9.0.
If you're mentioned at the start of a line, the to-do item you receive is
listed as *directly addressed*. For example, in the following comment:
You can create a to-do item by directly addressing someone at the start of a line.
For example, in the following comment:
```markdown
@alice What do you think? cc: @bob
@ -86,22 +84,15 @@ listed as *directly addressed*. For example, in the following comment:
@erin @frank thank you!
```
The people receiving directly addressed to-do items are `@alice`, `@erin`, and
`@frank`. Directly addressed to-do items only differ from mentions in their type
for filtering purposes; otherwise, they appear as normal.
The people who receive to-do items are `@alice`, `@erin`, and
`@frank`.
### Manually creating a to-do item
To view to-do items where a user was directly addressed, go to the To-Do List and
from the **Action** filter, select **Directly addressed**.
You can also add the following to your To-Do List by clicking the **Add a to do** button on:
Mentioning a user many times only creates one to-do item.
- [Issues](project/issues/index.md)
- [Merge requests](project/merge_requests/index.md)
- [Epics](group/epics/index.md)
- [Designs](project/issues/design_management.md)
![Adding a to-do item from the issuable sidebar](img/todos_add_todo_sidebar_v14_1.png)
## Marking a to-do item as done
## Actions that mark a to-do item as done
Any action to an issue, merge request, or epic marks its
corresponding to-do item as done.
@ -110,53 +101,36 @@ Actions that dismiss to-do items include:
- Changing the assignee
- Changing the milestone
- Adding/removing a label
- Closing the issue or merge request
- Adding or removing a label
- Commenting on the issue
- Resolving a [design discussion thread](project/issues/design_management.md#resolve-design-threads)
Your To-Do List is personal, and items are only marked as done if you take
action. If you close the issue or merge request, your to-do item is marked as
done.
To prevent other users from closing issues without you being notified, if
someone else closes, merges, or takes action on an issue, merge request, or
If someone else closes, merges, or takes action on an issue, merge request, or
epic, your to-do item remains pending.
There's just one to-do item for each of these, so mentioning a user many times
in an issue only triggers one to-do item.
## Mark a to-do item as done
If no action is needed, you can manually mark the to-do item as done by
clicking its corresponding **Done** button to have GitLab remove the item from
your To-Do List.
You can manually mark a to-do item as done.
![A to-do in the To-Do List](img/todos_todo_list_item.png)
There are two ways to do this:
You can also mark a to-do item as done by clicking the **Mark as done** button
in the sidebar of an issue, merge request, or epic.
- In the To-Do List, to the right of the to-do item, select **Done**.
- In the sidebar of an issue, merge request, or epic, select **Mark as done**.
![Mark as done from the issuable sidebar](img/todos_mark_done_sidebar_v14_1.png)
![Mark as done from the sidebar](img/todos_mark_done_sidebar_v14_1.png)
You can mark all your to-do items as done at once by clicking the
**Mark all as done** button.
## Mark all to-do items as done
## Filtering your To-Do List
You can mark all your to-do items as done at the same time.
You can use the following types of filters with your To-Do List:
In the To-Do List, in the top right, select **Mark all as done**.
| Filter | Description |
| ------- | ---------------------------------------------------------------- |
| Project | Filter by project. |
| Group | Filter by group. |
| Author | Filter by the author that triggered the to-do item. |
| Type | Filter by issue, merge request, design, or epic. |
| Action | Filter by the action that triggered the to-do item. |
## How a user's To-Do List is affected when their access changes
You can also filter by more than one of these at the same time. The previously
described [triggering actions](#what-triggers-a-to-do-item) include:
For security reasons, GitLab deletes to-do items when a user no longer has access to a related resource.
For example, if the user no longer has access to an issue, merge request, epic, project, or group,
GitLab deletes the related to-do items.
- Any action
- Assigned
- Mentioned
- Added
- Pipelines
- Directly addressed
This process occurs in the hour after their access changes. Deletion is delayed to
prevent data loss, in case the user's access was accidentally revoked.

View File

@ -57,7 +57,7 @@ module Gitlab
# Sets a cache key to the given value.
#
# key - The cache key to write.
# raw_key - The cache key to write.
# value - The value to set.
# timeout - The time after which the cache key should expire.
def self.write(raw_key, value, timeout: TIMEOUT)
@ -73,7 +73,7 @@ module Gitlab
# Increment the integer value of a key by one.
# Sets the value to zero if missing before incrementing
#
# key - The cache key to increment.
# raw_key - The cache key to increment.
# timeout - The time after which the cache key should expire.
# @return - the incremented value
def self.increment(raw_key, timeout: TIMEOUT)
@ -85,6 +85,22 @@ module Gitlab
end
end
# Increment the integer value of a key by the given value.
# Sets the value to zero if missing before incrementing
#
# raw_key - The cache key to increment.
# value - The value to increment the key
# timeout - The time after which the cache key should expire.
# @return - the incremented value
def self.increment_by(raw_key, value, timeout: TIMEOUT)
key = cache_key_for(raw_key)
Redis::Cache.with do |redis|
redis.incrby(key, value)
redis.expire(key, timeout)
end
end
# Adds a value to a set.
#
# raw_key - The key of the set to add the value to.

View File

@ -3,23 +3,60 @@
module Gitlab
module GithubImport
module BulkImporting
attr_reader :project, :client
# project - An instance of `Project`.
# client - An instance of `Gitlab::GithubImport::Client`.
def initialize(project, client)
@project = project
@client = client
end
# Builds and returns an Array of objects to bulk insert into the
# database.
#
# enum - An Enumerable that returns the objects to turn into database
# rows.
def build_database_rows(enum)
enum.each_with_object([]) do |(object, _), rows|
rows << build(object) unless already_imported?(object)
rows = enum.each_with_object([]) do |(object, _), result|
result << build(object) unless already_imported?(object)
end
log_and_increment_counter(rows.size, :fetched)
rows
end
# Bulk inserts the given rows into the database.
def bulk_insert(model, rows, batch_size: 100)
rows.each_slice(batch_size) do |slice|
Gitlab::Database.bulk_insert(model.table_name, slice) # rubocop:disable Gitlab/BulkInsert
log_and_increment_counter(slice.size, :imported)
end
end
def object_type
raise NotImplementedError
end
private
def log_and_increment_counter(value, operation)
Gitlab::Import::Logger.info(
import_source: :github,
project_id: project.id,
importer: self.class.name,
message: "#{value} #{object_type.to_s.pluralize} #{operation}"
)
Gitlab::GithubImport::ObjectCounter.increment(
project,
object_type,
operation,
value: value
)
end
end
end
end

View File

@ -6,15 +6,9 @@ module Gitlab
class LabelsImporter
include BulkImporting
attr_reader :project, :client, :existing_labels
# project - An instance of `Project`.
# client - An instance of `Gitlab::GithubImport::Client`.
# rubocop: disable CodeReuse/ActiveRecord
def initialize(project, client)
@project = project
@client = client
@existing_labels = project.labels.pluck(:title).to_set
def existing_labels
@existing_labels ||= project.labels.pluck(:title).to_set
end
# rubocop: enable CodeReuse/ActiveRecord
@ -51,6 +45,10 @@ module Gitlab
def each_label
client.labels(project.import_source)
end
def object_type
:label
end
end
end
end

View File

@ -6,15 +6,9 @@ module Gitlab
class MilestonesImporter
include BulkImporting
attr_reader :project, :client, :existing_milestones
# project - An instance of `Project`
# client - An instance of `Gitlab::GithubImport::Client`
# rubocop: disable CodeReuse/ActiveRecord
def initialize(project, client)
@project = project
@client = client
@existing_milestones = project.milestones.pluck(:iid).to_set
def existing_milestones
@existing_milestones ||= project.milestones.pluck(:iid).to_set
end
# rubocop: enable CodeReuse/ActiveRecord
@ -55,6 +49,10 @@ module Gitlab
def each_milestone
client.milestones(project.import_source, state: 'all')
end
def object_type
:milestone
end
end
end
end

View File

@ -6,15 +6,9 @@ module Gitlab
class ReleasesImporter
include BulkImporting
attr_reader :project, :client, :existing_tags
# project - An instance of `Project`
# client - An instance of `Gitlab::GithubImport::Client`
# rubocop: disable CodeReuse/ActiveRecord
def initialize(project, client)
@project = project
@client = client
@existing_tags = project.releases.pluck(:tag).to_set
def existing_tags
@existing_tags ||= project.releases.pluck(:tag).to_set
end
# rubocop: enable CodeReuse/ActiveRecord
@ -50,6 +44,10 @@ module Gitlab
def description_for(release)
release.body.presence || "Release for tag #{release.tag_name}"
end
def object_type
:release
end
end
end
end

View File

@ -14,11 +14,16 @@ module Gitlab
CACHING = Gitlab::Cache::Import::Caching
class << self
def increment(project, object_type, operation)
# Increments the project and the global counters if the given value is >= 1
def increment(project, object_type, operation, value: 1)
integer = value.to_i
return if integer <= 0
validate_operation!(operation)
increment_project_counter(project, object_type, operation)
increment_global_counter(object_type, operation)
increment_project_counter(project, object_type, operation, integer)
increment_global_counter(object_type, operation, integer)
end
def summary(project)
@ -41,7 +46,7 @@ module Gitlab
# and it's used to report the health of the Github Importer
# in the Grafana Dashboard
# https://dashboards.gitlab.net/d/2zgM_rImz/github-importer?orgId=1
def increment_global_counter(object_type, operation)
def increment_global_counter(object_type, operation, value)
key = GLOBAL_COUNTER_KEY % {
operation: operation,
object_type: object_type
@ -51,18 +56,26 @@ module Gitlab
object_type: object_type.to_s.humanize
}
Gitlab::Metrics.counter(key.to_sym, description).increment
Gitlab::Metrics.counter(key.to_sym, description).increment(by: value)
end
# Project counters are short lived, in Redis,
# and it's used to report how successful a project
# import was with the #summary method.
def increment_project_counter(project, object_type, operation)
counter_key = PROJECT_COUNTER_KEY % { project: project.id, operation: operation, object_type: object_type }
def increment_project_counter(project, object_type, operation, value)
counter_key = PROJECT_COUNTER_KEY % {
project: project.id,
operation: operation,
object_type: object_type
}
add_counter_to_list(project, operation, counter_key)
CACHING.increment(counter_key)
if Feature.disabled?(:import_redis_increment_by, default_enabled: :yaml)
CACHING.increment(counter_key)
else
CACHING.increment_by(counter_key, value)
end
end
def add_counter_to_list(project, operation, key)
@ -75,7 +88,7 @@ module Gitlab
def validate_operation!(operation)
unless operation.to_s.presence_in(OPERATIONS)
raise ArgumentError, "Operation must be #{OPERATIONS.join(' or ')}"
raise ArgumentError, "operation must be #{OPERATIONS.join(' or ')}"
end
end
end

View File

@ -181,6 +181,24 @@ RSpec.describe Projects::SnippetsController do
end
end
end
context 'when the project snippet is public' do
let_it_be(:project_snippet_public) { create(:project_snippet, :public, :repository, project: project, author: user) }
context 'when attempting to access from a different project route' do
subject { get action, params: { namespace_id: project.namespace, project_id: 42, id: project_snippet_public.to_param } }
before do
sign_in(user)
end
it 'responds with status 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
end

View File

@ -3,8 +3,20 @@
require 'spec_helper'
RSpec.describe Gitlab::GithubImport::BulkImporting do
let(:importer) do
Class.new { include(Gitlab::GithubImport::BulkImporting) }.new
let(:project) { instance_double(Project, id: 1) }
let(:importer) { MyImporter.new(project, double) }
let(:importer_class) do
Class.new do
include Gitlab::GithubImport::BulkImporting
def object_type
:object_type
end
end
end
before do
stub_const 'MyImporter', importer_class
end
describe '#build_database_rows' do
@ -21,6 +33,24 @@ RSpec.describe Gitlab::GithubImport::BulkImporting do
.with(object)
.and_return(false)
expect(Gitlab::Import::Logger)
.to receive(:info)
.with(
import_source: :github,
project_id: 1,
importer: 'MyImporter',
message: '1 object_types fetched'
)
expect(Gitlab::GithubImport::ObjectCounter)
.to receive(:increment)
.with(
project,
:object_type,
:fetched,
value: 1
)
enum = [[object, 1]].to_enum
expect(importer.build_database_rows(enum)).to eq([{ title: 'Foo' }])
@ -37,6 +67,24 @@ RSpec.describe Gitlab::GithubImport::BulkImporting do
.with(object)
.and_return(true)
expect(Gitlab::Import::Logger)
.to receive(:info)
.with(
import_source: :github,
project_id: 1,
importer: 'MyImporter',
message: '0 object_types fetched'
)
expect(Gitlab::GithubImport::ObjectCounter)
.to receive(:increment)
.with(
project,
:object_type,
:fetched,
value: 0
)
enum = [[object, 1]].to_enum
expect(importer.build_database_rows(enum)).to be_empty
@ -48,6 +96,26 @@ RSpec.describe Gitlab::GithubImport::BulkImporting do
rows = [{ title: 'Foo' }] * 10
model = double(:model, table_name: 'kittens')
expect(Gitlab::Import::Logger)
.to receive(:info)
.twice
.with(
import_source: :github,
project_id: 1,
importer: 'MyImporter',
message: '5 object_types imported'
)
expect(Gitlab::GithubImport::ObjectCounter)
.to receive(:increment)
.twice
.with(
project,
:object_type,
:imported,
value: 5
)
expect(Gitlab::Database)
.to receive(:bulk_insert)
.ordered

View File

@ -7,7 +7,7 @@ RSpec.describe Gitlab::GithubImport::ObjectCounter, :clean_gitlab_redis_cache do
it 'validates the operation being incremented' do
expect { described_class.increment(project, :issue, :unknown) }
.to raise_error(ArgumentError, 'Operation must be fetched or imported')
.to raise_error(ArgumentError, 'operation must be fetched or imported')
end
it 'increments the counter and saves the key to be listed in the summary later' do
@ -33,4 +33,20 @@ RSpec.describe Gitlab::GithubImport::ObjectCounter, :clean_gitlab_redis_cache do
'imported' => { 'issue' => 2 }
})
end
it 'does not increment the counter if the given value is <= 0' do
expect(Gitlab::Metrics)
.not_to receive(:counter)
expect(Gitlab::Metrics)
.not_to receive(:counter)
described_class.increment(project, :issue, :fetched, value: 0)
described_class.increment(project, :issue, :imported, value: nil)
expect(described_class.summary(project)).to eq({
'fetched' => {},
'imported' => {}
})
end
end