Add latest changes from gitlab-org/gitlab@master
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 895 B |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 580 B |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 923 B |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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'));
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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**.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||

|
||||
## 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**.
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
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**.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||