summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/administration/auth/ldap-ee.md126
-rw-r--r--doc/administration/auth/ldap.md50
-rw-r--r--doc/administration/geo/replication/index.md67
-rw-r--r--doc/administration/gitaly/index.md91
-rw-r--r--doc/api/README.md7
-rw-r--r--doc/api/jobs.md6
-rw-r--r--doc/ci/ci_cd_for_external_repos/bitbucket_integration.md198
-rw-r--r--doc/ci/docker/using_docker_build.md342
-rw-r--r--doc/ci/docker/using_docker_images.md131
-rw-r--r--doc/ci/examples/artifactory_and_gitlab/index.md70
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md111
-rw-r--r--doc/ci/ssh_keys/README.md82
-rw-r--r--doc/ci/variables/README.md7
-rw-r--r--doc/ci/yaml/README.md16
-rw-r--r--doc/development/fe_guide/event_tracking.md93
-rw-r--r--doc/development/testing_guide/review_apps.md31
-rw-r--r--doc/install/installation.md2
-rw-r--r--doc/security/README.md2
-rw-r--r--doc/security/rack_attack.md77
-rw-r--r--doc/security/rate_limits.md32
-rw-r--r--doc/topics/autodevops/index.md6
-rw-r--r--doc/user/admin_area/settings/img/user_and_ip_rate_limits.pngbin0 -> 232777 bytes
-rw-r--r--doc/user/admin_area/settings/index.md1
-rw-r--r--doc/user/admin_area/settings/user_and_ip_rate_limits.md32
-rw-r--r--doc/user/application_security/dast/index.md5
-rw-r--r--doc/user/application_security/index.md32
-rw-r--r--doc/user/gitlab_com/index.md73
-rw-r--r--doc/user/project/img/key_value_labels.pngbin6208 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_default.pngbin35620 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_default_v12_1.pngbin0 -> 207994 bytes
-rw-r--r--doc/user/project/img/labels_delete_v12_1.pngbin0 -> 29186 bytes
-rw-r--r--doc/user/project/img/labels_drag_priority_v12_1.gifbin0 -> 958437 bytes
-rw-r--r--doc/user/project/img/labels_epic_sidebar.pngbin47869 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_epic_sidebar_v12_1.pngbin0 -> 318960 bytes
-rw-r--r--doc/user/project/img/labels_generate_default.pngbin25797 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_generate_default_v12_1.pngbin0 -> 244739 bytes
-rw-r--r--doc/user/project/img/labels_group_issues.pngbin92070 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_group_issues_v12_1.pngbin0 -> 391121 bytes
-rw-r--r--doc/user/project/img/labels_key_value_v12_1.pngbin0 -> 332077 bytes
-rw-r--r--doc/user/project/img/labels_list.pngbin75215 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_list_v12_1.pngbin0 -> 360298 bytes
-rw-r--r--doc/user/project/img/labels_new_label_from_sidebar.gif (renamed from doc/user/project/img/new_label_from_sidebar.gif)bin759243 -> 759243 bytes
-rw-r--r--doc/user/project/img/labels_prioritized.pngbin56353 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_prioritized_v12_1.pngbin0 -> 178652 bytes
-rw-r--r--doc/user/project/img/labels_promotion.pngbin44021 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_promotion_v12_1.pngbin0 -> 29215 bytes
-rw-r--r--doc/user/project/img/labels_subscriptions.pngbin31716 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_subscriptions_v12_1.pngbin0 -> 138684 bytes
-rw-r--r--doc/user/project/integrations/jira_server_configuration.md4
-rw-r--r--doc/user/project/labels.md183
-rw-r--r--doc/user/project/merge_requests/merge_request_approvals.md10
-rw-r--r--doc/user/project/packages/npm_registry.md30
-rw-r--r--doc/workflow/shortcuts.md10
53 files changed, 1220 insertions, 707 deletions
diff --git a/doc/administration/auth/ldap-ee.md b/doc/administration/auth/ldap-ee.md
index 1b7af2d945a..34f3cfa353f 100644
--- a/doc/administration/auth/ldap-ee.md
+++ b/doc/administration/auth/ldap-ee.md
@@ -4,37 +4,27 @@ type: reference
# LDAP Additions in GitLab EE **(STARTER ONLY)**
-This is a continuation of the main [LDAP documentation](ldap.md), detailing LDAP
-features specific to GitLab Enterprise Edition Starter, Premium and Ultimate.
+This section documents LDAP features specific to to GitLab Enterprise Edition
+[Starter](https://about.gitlab.com/pricing/#self-managed) and above.
-## Overview
-
-[LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
-stands for **Lightweight Directory Access Protocol**, which
-is a standard application protocol for
-accessing and maintaining distributed directory information services
-over an Internet Protocol (IP) network.
-
-GitLab integrates with LDAP to support **user authentication**. This integration
-works with most LDAP-compliant directory servers, including Microsoft Active
-Directory, Apple Open Directory, Open LDAP, and 389 Server.
-**GitLab Enterprise Edition** includes enhanced integration, including group
-membership syncing.
+For documentation relevant to both Community Edition and Enterprise Edition,
+see the main [LDAP documentation](ldap.md).
## Use cases
-- User sync: Once a day, GitLab will update users against LDAP
+- User sync: Once a day, GitLab will update users against LDAP.
- Group sync: Once an hour, GitLab will update group membership
- based on LDAP group members
+ based on LDAP group members.
-## Multiple LDAP servers
+## Multiple LDAP servers **(STARTER ONLY)**
With GitLab Enterprise Edition Starter, you can configure multiple LDAP servers
that your GitLab instance will connect to.
-To add another LDAP server, you can start by duplicating the settings under
-[the main configuration](ldap.md#configuration) and edit them to match the
-additional LDAP server.
+To add another LDAP server:
+
+1. Duplicating the settings under [the main configuration](ldap.md#configuration).
+1. Edit them to match the additional LDAP server.
Be sure to choose a different provider ID made of letters a-z and numbers 0-9.
This ID will be stored in the database so that GitLab can remember which LDAP
@@ -47,19 +37,19 @@ users against LDAP.
The process will execute the following access checks:
-1. Ensure the user is still present in LDAP
-1. If the LDAP server is Active Directory, ensure the user is active (not
- blocked/disabled state). This will only be checked if
- `active_directory: true` is set in the LDAP configuration [^1]
+- Ensure the user is still present in LDAP.
+- If the LDAP server is Active Directory, ensure the user is active (not
+ blocked/disabled state). This will only be checked if
+ `active_directory: true` is set in the LDAP configuration. [^1]
The user will be set to `ldap_blocked` state in GitLab if the above conditions
fail. This means the user will not be able to login or push/pull code.
The process will also update the following user information:
-1. Email address
-1. If `sync_ssh_keys` is set, SSH public keys
-1. If Kerberos is enabled, Kerberos identity
+- Email address.
+- If `sync_ssh_keys` is set, SSH public keys.
+- If Kerberos is enabled, Kerberos identity.
NOTE: **Note:**
The LDAP sync process updates existing users while new users will
@@ -72,9 +62,6 @@ first time GitLab will trigger a sync for groups the user should be a member of.
That way they don't need to wait for the hourly sync to be granted
access to their groups and projects.
-In GitLab Premium, we can also add a GitLab group to sync with one or multiple LDAP groups or we can
-also add a filter. The filter must comply with the syntax defined in [RFC 2254](https://tools.ietf.org/search/rfc2254).
-
A group sync process will run every hour on the hour, and `group_base` must be set
in LDAP configuration for LDAP synchronizations based on group CN to work. This allows
GitLab group membership to be automatically updated based on LDAP group members.
@@ -120,13 +107,26 @@ following.
1. [Restart GitLab][restart] for the changes to take effect.
----
-
To take advantage of group sync, group owners or maintainers will need to create an
-LDAP group link in their group **Settings > LDAP Groups** page. Multiple LDAP
-groups and/or filters can be linked with a single GitLab group. When the link is
-created, an access level/role is specified (Guest, Reporter, Developer, Maintainer,
-or Owner).
+LDAP group link in their group **Settings > LDAP Groups** page.
+
+Multiple LDAP groups and [filters](#filters-premium-only) can be linked with
+a single GitLab group. When the link is created, an access level/role is
+specified (Guest, Reporter, Developer, Maintainer, or Owner).
+
+### Filters **(PREMIUM ONLY)**
+
+In GitLab Premium, you can add an LDAP user filter for group synchronization.
+Filters allow for complex logic without creating a special LDAP group.
+
+To sync GitLab group membership based on an LDAP filter:
+
+1. Open the **LDAP Synchronization** page for the GitLab group.
+1. Select **LDAP user filter** as the **Sync method**.
+1. Enter an LDAP user filter in the **LDAP user filter** field.
+
+The filter must comply with the
+syntax defined in [RFC 2254](https://tools.ietf.org/search/rfc2254).
## Administrator sync
@@ -190,10 +190,13 @@ group, as opposed to the full DN.
## Global group memberships lock
"Lock memberships to LDAP synchronization" setting allows instance administrators
-to lock down user abilities to invite new members to a group. When enabled following happens:
+to lock down user abilities to invite new members to a group.
+
+When enabled, the following applies:
-1. Only administrator can manage memberships of any group including access levels.
-1. Users are not allowed to share project with other groups or invite members to a project created in a group.
+- Only administrator can manage memberships of any group including access levels.
+- Users are not allowed to share project with other groups or invite members to
+ a project created in a group.
## Adjusting LDAP user sync schedule
@@ -333,10 +336,18 @@ administrative duties.
### Supported LDAP group types/attributes
-GitLab supports LDAP groups that use member attributes `member`, `submember`,
-`uniquemember`, `memberof` and `memberuid`. This means group sync supports, at
-least, LDAP groups with object class `groupOfNames`, `posixGroup`, and
-`groupOfUniqueName`. Other object classes should work fine as long as members
+GitLab supports LDAP groups that use member attributes:
+
+- `member`
+- `submember`
+- `uniquemember`
+- `memberof`
+- `memberuid`.
+
+This means group sync supports, at least, LDAP groups with object class:
+`groupOfNames`, `posixGroup`, and `groupOfUniqueName`.
+
+Other object classes should work fine as long as members
are defined as one of the mentioned attributes. This also means GitLab supports
Microsoft Active Directory, Apple Open Directory, Open LDAP, and 389 Server.
Other LDAP servers should work, too.
@@ -344,11 +355,12 @@ Other LDAP servers should work, too.
Active Directory also supports nested groups. Group sync will recursively
resolve membership if `active_directory: true` is set in the configuration file.
-> **Note:** Nested group membership will only be resolved if the nested group
- also falls within the configured `group_base`. For example, if GitLab sees a
- nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but
- the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group`
- will be ignored.
+NOTE: **Note:**
+Nested group membership will only be resolved if the nested group
+also falls within the configured `group_base`. For example, if GitLab sees a
+nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but
+the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group`
+will be ignored.
### Queries
@@ -403,7 +415,7 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server
[^1]: In Active Directory, a user is marked as disabled/blocked if the user
account control attribute (`userAccountControl:1.2.840.113556.1.4.803`)
- has bit 2 set. See https://ctogonewild.com/2009/09/03/bitmask-searches-in-ldap/
+ has bit 2 set. See <https://ctogonewild.com/2009/09/03/bitmask-searches-in-ldap/>
for more information.
### User DN has changed
@@ -423,10 +435,10 @@ things to check to debug the situation.
- Ensure LDAP configuration has a `group_base` specified. This configuration is
required for group sync to work properly.
- Ensure the correct LDAP group link is added to the GitLab group. Check group
- links by visiting the GitLab group, then **Settings dropdown -> LDAP groups**.
-- Check that the user has an LDAP identity
+ links by visiting the GitLab group, then **Settings dropdown > LDAP groups**.
+- Check that the user has an LDAP identity:
1. Sign in to GitLab as an administrator user.
- 1. Navigate to **Admin area -> Users**.
+ 1. Navigate to **Admin area > Users**.
1. Search for the user
1. Open the user, by clicking on their name. Do not click 'Edit'.
1. Navigate to the **Identities** tab. There should be an LDAP identity with
@@ -437,7 +449,7 @@ Often, the best way to learn more about why group sync is behaving a certain
way is to enable debug logging. There is verbose output that details every
step of the sync.
-1. Start a Rails console
+1. Start a Rails console:
```bash
# For Omnibus installations
@@ -446,6 +458,7 @@ step of the sync.
# For installations from source
sudo -u git -H bundle exec rails console production
```
+
1. Set the log level to debug (only for this session):
```ruby
@@ -540,8 +553,9 @@ and more DNs may be added, or existing entries modified, based on additional
LDAP group lookups. The very last occurrence of this entry should indicate
exactly which users GitLab believes should be added to the group.
-> **Note:** 10 is 'Guest', 20 is 'Reporter', 30 is 'Developer', 40 is 'Maintainer'
- and 50 is 'Owner'
+NOTE: **Note:**
+10 is 'Guest', 20 is 'Reporter', 30 is 'Developer', 40 is 'Maintainer'
+and 50 is 'Owner'.
```bash
Resolved 'my_group' group member access: {"uid=john0,ou=people,dc=example,dc=com"=>30,
diff --git a/doc/administration/auth/ldap.md b/doc/administration/auth/ldap.md
index be05a4d63a7..beacaa99d60 100644
--- a/doc/administration/auth/ldap.md
+++ b/doc/administration/auth/ldap.md
@@ -7,16 +7,29 @@ type: reference
# LDAP
GitLab integrates with LDAP to support user authentication.
-This integration works with most LDAP-compliant directory
-servers, including Microsoft Active Directory, Apple Open Directory, Open LDAP,
-and 389 Server. GitLab Enterprise Editions include enhanced integration,
+
+This integration works with most LDAP-compliant directory servers, including:
+
+- Microsoft Active Directory
+- Apple Open Directory
+- Open LDAP
+- 389 Server.
+
+GitLab Enterprise Editions (EE) include enhanced integration,
including group membership syncing as well as multiple LDAP servers support.
-## GitLab EE
+For more details about EE-specific LDAP features, see the
+[LDAP Enterprise Edition documentation](ldap-ee.md).
-The information on this page is relevant for both GitLab CE and EE. For more
-details about EE-specific LDAP features, see the
-[LDAP Enterprise Edition documentation](ldap-ee.md). **(STARTER ONLY)**
+NOTE: **Note:**
+The information on this page is relevant for both GitLab CE and EE.
+
+## Overview
+
+[LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
+stands for **Lightweight Directory Access Protocol**, which is a standard
+application protocol for accessing and maintaining distributed directory
+information services over an Internet Protocol (IP) network.
## Security
@@ -64,9 +77,12 @@ NOTE: **Note**:
In GitLab Enterprise Edition Starter, you can configure multiple LDAP servers
to connect to one GitLab server.
-For a complete guide on configuring LDAP with GitLab Community Edition, please check
-the admin guide [How to configure LDAP with GitLab CE](how_to_configure_ldap_gitlab_ce/index.md).
-For GitLab Enterprise Editions, see also [How to configure LDAP with GitLab EE](how_to_configure_ldap_gitlab_ee/index.md). **(STARTER ONLY)**
+For a complete guide on configuring LDAP with:
+
+- GitLab Community Edition, see
+ [How to configure LDAP with GitLab CE](how_to_configure_ldap_gitlab_ce/index.md).
+- Enterprise Editions, see
+ [How to configure LDAP with GitLab EE](how_to_configure_ldap_gitlab_ee/index.md). **(STARTER ONLY)**
To enable LDAP integration you need to add your LDAP server settings in
`/etc/gitlab/gitlab.rb` or `/home/git/gitlab/config/gitlab.yml` for Omnibus
@@ -384,7 +400,7 @@ production:
Tip: If you want to limit access to the nested members of an Active Directory
group, you can use the following syntax:
-```
+```text
(memberOf:1.2.840.113556.1.4.1941:=CN=My Group,DC=Example,DC=com)
```
@@ -402,13 +418,13 @@ The `user_filter` DN can contain special characters. For example:
- A comma:
- ```
+ ```text
OU=GitLab, Inc,DC=gitlab,DC=com
```
- Open and close brackets:
- ```
+ ```text
OU=Gitlab (Inc),DC=gitlab,DC=com
```
@@ -417,13 +433,13 @@ The `user_filter` DN can contain special characters. For example:
- Escape commas with `\2C`. For example:
- ```
+ ```text
OU=GitLab\2C Inc,DC=gitlab,DC=com
```
- Escape open and close brackets with `\28` and `\29`, respectively. For example:
- ```
+ ```text
OU=Gitlab \28Inc\29,DC=gitlab,DC=com
```
@@ -507,11 +523,11 @@ timeout), the login is rejected and a message will be logged to
### Debug LDAP user filter with ldapsearch
-This example uses ldapsearch and assumes you are using ActiveDirectory. The
+This example uses `ldapsearch` and assumes you are using ActiveDirectory. The
following query returns the login names of the users that will be allowed to
log in to GitLab if you configure your own user_filter.
-```
+```sh
ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$base" "$user_filter" sAMAccountName
```
diff --git a/doc/administration/geo/replication/index.md b/doc/administration/geo/replication/index.md
index b5789c87e47..dc49a95e008 100644
--- a/doc/administration/geo/replication/index.md
+++ b/doc/administration/geo/replication/index.md
@@ -245,35 +245,48 @@ This list of limitations only reflects the latest version of GitLab. If you are
- Object pools for forked project deduplication work only on the **primary** node, and are duplicated on the **secondary** node.
- [External merge request diffs](../../merge_request_diffs.md) will not be replicated if they are on-disk, and viewing merge requests will fail. However, external MR diffs in object storage **are** supported. The default configuration (in-database) does work.
-### Limitations on replication
-
-Only the following items are replicated to the **secondary** node:
-
-- All database content. For example, snippets, epics, issues, merge requests, groups, and project metadata.
-- Project repositories.
-- Project wiki repositories.
-- User uploads. For example, attachments to issues, merge requests, epics, and avatars.
-- CI job artifacts and traces.
+### Limitations on replication/verification
+
+The following table lists the GitLab features along with their replication
+and verification status on a **secondary** node.
+
+You can keep track of the progress to include the missing items in:
+
+- [ee-893](https://gitlab.com/groups/gitlab-org/-/epics/893).
+- [ee-1430](https://gitlab.com/groups/gitlab-org/-/epics/1430).
+
+| Feature | Replicated | Verified |
+|-----------|------------|----------|
+| All database content (e.g. snippets, epics, issues, merge requests, groups, and project metadata) | Yes | Yes |
+| Project repository | Yes | Yes |
+| Project wiki repository | Yes | Yes |
+| Project designs repository | No | No |
+| Uploads (e.g. attachments to issues, merge requests, epics, and avatars) | Yes | Yes, only on transfer, or manually (1) |
+| LFS Objects | Yes | Yes, only on transfer, or manually (1) |
+| CI job artifacts (other than traces) | Yes | No, only manually (1) |
+| Archived traces | Yes | Yes, only on transfer, or manually (1) |
+| Personal snippets | Yes | Yes |
+| Version-controlled personal snippets ([unsupported](https://gitlab.com/gitlab-org/gitlab-ce/issues/13426)) | No | No |
+| Project snippets | Yes | Yes |
+| Version-controlled project snippets ([unsupported](https://gitlab.com/gitlab-org/gitlab-ce/issues/13426)) | No | No |
+| Object pools for forked project deduplication | No | No |
+| [Server-side Git Hooks](../../custom_hooks.md) | No | No |
+| [Elasticsearch integration](../../../integration/elasticsearch.md) | No | No |
+| [GitLab Pages](../../pages/index.md) | No | No |
+| [Container Registry](../../container_registry.md) ([track progress](https://gitlab.com/gitlab-org/gitlab-ee/issues/2870)) | No | No |
+| [NPM Registry](../../npm_registry.md) | No | No |
+| [Maven Packages](../../maven_packages.md) | No | No |
+| [External merge request diffs](../../merge_request_diffs.md) | No, if they are on-disk | No |
+| Content in object storage ([track progress](https://gitlab.com/groups/gitlab-org/-/epics/1526)) | No | No |
+
+1. The integrity can be verified manually using [Integrity Check Rake Task](../../raketasks/check.md) on both nodes and comparing the output between them.
DANGER: **DANGER**
-Data not on this list is unavailable on the **secondary** node. Failing over without manually replicating data not on this list will cause the data to be **lost**.
-
-### Examples of data not replicated
-
-Take special note that these examples of GitLab features are both:
-
-- Commonly used.
-- **Not** replicated by Geo at present.
-
-Examples include:
-
-- [Elasticsearch integration](../../../integration/elasticsearch.md).
-- [Container Registry](../../container_registry.md). [Object Storage](object_storage.md) can mitigate this.
-- [GitLab Pages](../../pages/index.md).
-- [Mattermost integration](https://docs.gitlab.com/omnibus/gitlab-mattermost/).
-
-CAUTION: **Caution:**
-If you wish to use them on a **secondary** node, or to execute a failover successfully, you will need to replicate their data using some other means.
+Features not on this list, or with **No** in the **Replicated** column,
+are not replicated on the **secondary** node. Failing over without manually
+replicating data from those features will cause the data to be **lost**.
+If you wish to use those features on a **secondary** node, or to execute a failover
+successfully, you must replicate their data using some other means.
## Frequently Asked Questions
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 0f547ef03bf..f6f02221fe3 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -510,3 +510,94 @@ implemented as calls to `gitaly-ruby`:
```
sum(rate(grpc_client_handled_total[5m])) by (grpc_method) > 0
```
+
+### Repository changes fail with a `401 Unauthorized` error
+
+If you're running Gitaly on its own server and notice that users can
+successfully clone and fetch repositories (via both SSH and HTTPS), but can't
+push to them or make changes to the repository in the web UI without getting a
+`401 Unauthorized` message, then it's possible Gitaly is failing to authenticate
+with the other nodes due to having the [wrong secrets file](#3-gitaly-server-configuration).
+
+Confirm the following are all true:
+
+- When any user performs a `git push` to any repository on this Gitaly node, it
+ fails with the following error (note the `401 Unauthorized`):
+
+ ```sh
+ remote: GitLab: 401 Unauthorized
+ To <REMOTE_URL>
+ ! [remote rejected] branch-name -> branch-name (pre-receive hook declined)
+ error: failed to push some refs to '<REMOTE_URL>'
+ ```
+
+- When any user adds or modifies a file from the repository using the GitLab
+ UI, it immediatley fails with a red `401 Unauthorized` banner.
+- Creating a new project and [initializing it with a README](../../gitlab-basics/create-project.md#blank-projects)
+ successfully creates the project but doesn't create the README.
+- When [tailing the logs](https://docs.gitlab.com/omnibus/settings/logs.md#tail-logs-in-a-console-on-the-server) on an app node and reproducing the error, you get `401` errors
+ when reaching the `/api/v4/internal/allowed` endpoint:
+
+ ```sh
+ # api_json.log
+ {
+ "time": "2019-07-18T00:30:14.967Z",
+ "severity": "INFO",
+ "duration": 0.57,
+ "db": 0,
+ "view": 0.57,
+ "status": 401,
+ "method": "POST",
+ "path": "\/api\/v4\/internal\/allowed",
+ "params": [
+ {
+ "key": "action",
+ "value": "git-receive-pack"
+ },
+ {
+ "key": "changes",
+ "value": "REDACTED"
+ },
+ {
+ "key": "gl_repository",
+ "value": "REDACTED"
+ },
+ {
+ "key": "project",
+ "value": "\/path\/to\/project.git"
+ },
+ {
+ "key": "protocol",
+ "value": "web"
+ },
+ {
+ "key": "env",
+ "value": "{\"GIT_ALTERNATE_OBJECT_DIRECTORIES\":[],\"GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE\":[],\"GIT_OBJECT_DIRECTORY\":null,\"GIT_OBJECT_DIRECTORY_RELATIVE\":null}"
+ },
+ {
+ "key": "user_id",
+ "value": "2"
+ },
+ {
+ "key": "secret_token",
+ "value": "[FILTERED]"
+ }
+ ],
+ "host": "gitlab.example.com",
+ "ip": "REDACTED",
+ "ua": "Ruby",
+ "route": "\/api\/:version\/internal\/allowed",
+ "queue_duration": 4.24,
+ "gitaly_calls": 0,
+ "gitaly_duration": 0,
+ "correlation_id": "XPUZqTukaP3"
+ }
+
+ # nginx_access.log
+ [IP] - - [18/Jul/2019:00:30:14 +0000] "POST /api/v4/internal/allowed HTTP/1.1" 401 30 "" "Ruby"
+ ```
+
+To fix this problem, confirm that your [`gitlab-secrets.json` file](#3-gitaly-server-configuration)
+on the Gitaly node matches the one on all other nodes. If it doesn't match,
+update the secrets file on the Gitaly node to match the others, then
+[reconfigure the node](../restart_gitlab.md#omnibus-gitlab-reconfigure).
diff --git a/doc/api/README.md b/doc/api/README.md
index 70540420544..6cd89e34921 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -695,6 +695,13 @@ The correct encoding for the query parameter would be:
There are many unofficial GitLab API Clients for most of the popular
programming languages. Visit the [GitLab website] for a complete list.
+## Rate limits
+
+For administrator documentation on rate limit settings, check out
+[Rate limits](../security/rate_limits.md). To find the settings that are
+specifically used by GitLab.com, see
+[GitLab.com-specific rate limits](../user/gitlab_com/index.md).
+
[GitLab website]: https://about.gitlab.com/applications/#api-clients "Clients using the GitLab API"
[lib-api-url]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/api/api.rb
[ce-3749]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3749
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index 0e45ee1a583..2a1c1b5f6f3 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -491,7 +491,7 @@ Parameters
Example request:
```sh
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/5/artifacts/some/release/file.pdf"
+curl --location --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/5/artifacts/some/release/file.pdf"
```
Possible response status codes:
@@ -526,7 +526,7 @@ Parameters:
Example request:
```sh
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/master/raw/some/release/file.pdf?job=pdf"
+curl --location --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/master/raw/some/release/file.pdf?job=pdf"
```
Possible response status codes:
@@ -551,7 +551,7 @@ GET /projects/:id/jobs/:job_id/trace
| job_id | integer | yes | ID of a job. |
```sh
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/8/trace"
+curl --location --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/8/trace"
```
Possible response status codes:
diff --git a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
index b3110b435db..8fe11140cc7 100644
--- a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
@@ -14,9 +14,9 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
1. In GitLab create a **CI/CD for external repo**, select **Repo by URL** and
create the project.
- ![Create project](img/external_repository.png)
+ ![Create project](img/external_repository.png)
- GitLab will import the repository and enable [Pull Mirroring][pull-mirroring].
+ GitLab will import the repository and enable [Pull Mirroring][pull-mirroring].
1. In GitLab create a
[Personal Access Token](../../user/profile/personal_access_tokens.md)
@@ -26,19 +26,19 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
1. In Bitbucket, from **Settings > Webhooks**, create a new web hook to notify
GitLab of new commits.
- The web hook URL should be set to the GitLab API to trigger pull mirroring,
- using the Personal Access Token we just generated for authentication.
+ The web hook URL should be set to the GitLab API to trigger pull mirroring,
+ using the Personal Access Token we just generated for authentication.
- ```text
- https://gitlab.com/api/v4/projects/<NAMESPACE>%2F<PROJECT>/mirror/pull?private_token=<PERSONAL_ACCESS_TOKEN>
- ```
+ ```text
+ https://gitlab.com/api/v4/projects/<NAMESPACE>%2F<PROJECT>/mirror/pull?private_token=<PERSONAL_ACCESS_TOKEN>
+ ```
- The web hook Trigger should be set to 'Repository Push'.
+ The web hook Trigger should be set to 'Repository Push'.
- ![Bitbucket Cloud webhook](img/bitbucket_webhook.png)
+ ![Bitbucket Cloud webhook](img/bitbucket_webhook.png)
- After saving, test the web hook by pushing a change to your Bitbucket
- repository.
+ After saving, test the web hook by pushing a change to your Bitbucket
+ repository.
1. In Bitbucket, create an **App Password** from **Bitbucket Settings > App
Passwords** to authenticate the build status script setting commit build
@@ -49,104 +49,104 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
1. In GitLab, from **Settings > CI/CD > Environment variables**, add variables to allow
communication with Bitbucket via the Bitbucket API:
- `BITBUCKET_ACCESS_TOKEN`: the Bitbucket app password created above.
+ `BITBUCKET_ACCESS_TOKEN`: the Bitbucket app password created above.
- `BITBUCKET_USERNAME`: the username of the Bitbucket account.
+ `BITBUCKET_USERNAME`: the username of the Bitbucket account.
- `BITBUCKET_NAMESPACE`: set this if your GitLab and Bitbucket namespaces differ.
+ `BITBUCKET_NAMESPACE`: set this if your GitLab and Bitbucket namespaces differ.
- `BITBUCKET_REPOSITORY`: set this if your GitLab and Bitbucket project names differ.
+ `BITBUCKET_REPOSITORY`: set this if your GitLab and Bitbucket project names differ.
1. In Bitbucket, add a script to push the pipeline status to Bitbucket.
- > Note: changes made in GitLab will be overwritten by any changes made
- > upstream in Bitbucket.
-
- Create a file `build_status` and insert the script below and run
- `chmod +x build_status` in your terminal to make the script executable.
-
- ```bash
- #!/usr/bin/env bash
-
- # Push GitLab CI/CD build status to Bitbucket Cloud
-
- if [ -z "$BITBUCKET_ACCESS_TOKEN" ]; then
- echo "ERROR: BITBUCKET_ACCESS_TOKEN is not set"
- exit 1
- fi
- if [ -z "$BITBUCKET_USERNAME" ]; then
- echo "ERROR: BITBUCKET_USERNAME is not set"
- exit 1
- fi
- if [ -z "$BITBUCKET_NAMESPACE" ]; then
- echo "Setting BITBUCKET_NAMESPACE to $CI_PROJECT_NAMESPACE"
- BITBUCKET_NAMESPACE=$CI_PROJECT_NAMESPACE
- fi
- if [ -z "$BITBUCKET_REPOSITORY" ]; then
- echo "Setting BITBUCKET_REPOSITORY to $CI_PROJECT_NAME"
- BITBUCKET_REPOSITORY=$CI_PROJECT_NAME
- fi
-
- BITBUCKET_API_ROOT="https://api.bitbucket.org/2.0"
- BITBUCKET_STATUS_API="$BITBUCKET_API_ROOT/repositories/$BITBUCKET_NAMESPACE/$BITBUCKET_REPOSITORY/commit/$CI_COMMIT_SHA/statuses/build"
- BITBUCKET_KEY="ci/gitlab-ci/$CI_JOB_NAME"
-
- case "$BUILD_STATUS" in
- running)
- BITBUCKET_STATE="INPROGRESS"
- BITBUCKET_DESCRIPTION="The build is running!"
- ;;
- passed)
- BITBUCKET_STATE="SUCCESSFUL"
- BITBUCKET_DESCRIPTION="The build passed!"
- ;;
- failed)
- BITBUCKET_STATE="FAILED"
- BITBUCKET_DESCRIPTION="The build failed."
- ;;
- esac
-
- echo "Pushing status to $BITBUCKET_STATUS_API..."
- curl --request POST $BITBUCKET_STATUS_API \
- --user $BITBUCKET_USERNAME:$BITBUCKET_ACCESS_TOKEN \
- --header "Content-Type:application/json" \
- --silent \
- --data "{ \"state\": \"$BITBUCKET_STATE\", \"key\": \"$BITBUCKET_KEY\", \"description\":
- \"$BITBUCKET_DESCRIPTION\",\"url\": \"$CI_PROJECT_URL/-/jobs/$CI_JOB_ID\" }"
- ```
+ > Note: changes made in GitLab will be overwritten by any changes made
+ > upstream in Bitbucket.
+
+ Create a file `build_status` and insert the script below and run
+ `chmod +x build_status` in your terminal to make the script executable.
+
+ ```bash
+ #!/usr/bin/env bash
+
+ # Push GitLab CI/CD build status to Bitbucket Cloud
+
+ if [ -z "$BITBUCKET_ACCESS_TOKEN" ]; then
+ echo "ERROR: BITBUCKET_ACCESS_TOKEN is not set"
+ exit 1
+ fi
+ if [ -z "$BITBUCKET_USERNAME" ]; then
+ echo "ERROR: BITBUCKET_USERNAME is not set"
+ exit 1
+ fi
+ if [ -z "$BITBUCKET_NAMESPACE" ]; then
+ echo "Setting BITBUCKET_NAMESPACE to $CI_PROJECT_NAMESPACE"
+ BITBUCKET_NAMESPACE=$CI_PROJECT_NAMESPACE
+ fi
+ if [ -z "$BITBUCKET_REPOSITORY" ]; then
+ echo "Setting BITBUCKET_REPOSITORY to $CI_PROJECT_NAME"
+ BITBUCKET_REPOSITORY=$CI_PROJECT_NAME
+ fi
+
+ BITBUCKET_API_ROOT="https://api.bitbucket.org/2.0"
+ BITBUCKET_STATUS_API="$BITBUCKET_API_ROOT/repositories/$BITBUCKET_NAMESPACE/$BITBUCKET_REPOSITORY/commit/$CI_COMMIT_SHA/statuses/build"
+ BITBUCKET_KEY="ci/gitlab-ci/$CI_JOB_NAME"
+
+ case "$BUILD_STATUS" in
+ running)
+ BITBUCKET_STATE="INPROGRESS"
+ BITBUCKET_DESCRIPTION="The build is running!"
+ ;;
+ passed)
+ BITBUCKET_STATE="SUCCESSFUL"
+ BITBUCKET_DESCRIPTION="The build passed!"
+ ;;
+ failed)
+ BITBUCKET_STATE="FAILED"
+ BITBUCKET_DESCRIPTION="The build failed."
+ ;;
+ esac
+
+ echo "Pushing status to $BITBUCKET_STATUS_API..."
+ curl --request POST $BITBUCKET_STATUS_API \
+ --user $BITBUCKET_USERNAME:$BITBUCKET_ACCESS_TOKEN \
+ --header "Content-Type:application/json" \
+ --silent \
+ --data "{ \"state\": \"$BITBUCKET_STATE\", \"key\": \"$BITBUCKET_KEY\", \"description\":
+ \"$BITBUCKET_DESCRIPTION\",\"url\": \"$CI_PROJECT_URL/-/jobs/$CI_JOB_ID\" }"
+ ```
1. Still in Bitbucket, create a `.gitlab-ci.yml` file to use the script to push
pipeline success and failures to Bitbucket.
- ```yaml
- stages:
- - test
- - ci_status
-
- unit-tests:
- script:
- - echo "Success. Add your tests!"
-
- success:
- stage: ci_status
- before_script:
- - ""
- after_script:
- - ""
- script:
- - BUILD_STATUS=passed BUILD_KEY=push ./build_status
- when: on_success
-
- failure:
- stage: ci_status
- before_script:
- - ""
- after_script:
- - ""
- script:
- - BUILD_STATUS=failed BUILD_KEY=push ./build_status
- when: on_failure
- ```
+ ```yaml
+ stages:
+ - test
+ - ci_status
+
+ unit-tests:
+ script:
+ - echo "Success. Add your tests!"
+
+ success:
+ stage: ci_status
+ before_script:
+ - ""
+ after_script:
+ - ""
+ script:
+ - BUILD_STATUS=passed BUILD_KEY=push ./build_status
+ when: on_success
+
+ failure:
+ stage: ci_status
+ before_script:
+ - ""
+ after_script:
+ - ""
+ script:
+ - BUILD_STATUS=failed BUILD_KEY=push ./build_status
+ when: on_failure
+ ```
GitLab is now configured to mirror changes from Bitbucket, run CI/CD pipelines
configured in `.gitlab-ci.yml` and push the status to Bitbucket.
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index 10a21edbd34..278a0d6e934 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -48,42 +48,42 @@ GitLab Runner then executes job scripts as the `gitlab-runner` user.
1. During GitLab Runner installation select `shell` as method of executing job scripts or use command:
- ```bash
- sudo gitlab-runner register -n \
- --url https://gitlab.com/ \
- --registration-token REGISTRATION_TOKEN \
- --executor shell \
- --description "My Runner"
- ```
+ ```bash
+ sudo gitlab-runner register -n \
+ --url https://gitlab.com/ \
+ --registration-token REGISTRATION_TOKEN \
+ --executor shell \
+ --description "My Runner"
+ ```
1. Install Docker Engine on server.
- For more information how to install Docker Engine on different systems
- checkout the [Supported installations](https://docs.docker.com/engine/installation/).
+ For more information how to install Docker Engine on different systems
+ checkout the [Supported installations](https://docs.docker.com/engine/installation/).
1. Add `gitlab-runner` user to `docker` group:
- ```bash
- sudo usermod -aG docker gitlab-runner
- ```
+ ```bash
+ sudo usermod -aG docker gitlab-runner
+ ```
1. Verify that `gitlab-runner` has access to Docker:
- ```bash
- sudo -u gitlab-runner -H docker info
- ```
+ ```bash
+ sudo -u gitlab-runner -H docker info
+ ```
- You can now verify that everything works by adding `docker info` to `.gitlab-ci.yml`:
+ You can now verify that everything works by adding `docker info` to `.gitlab-ci.yml`:
- ```yaml
- before_script:
- - docker info
+ ```yaml
+ before_script:
+ - docker info
- build_image:
- script:
- - docker build -t my-docker-image .
- - docker run my-docker-image /script/to/run/tests
- ```
+ build_image:
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+ ```
1. You can now use `docker` command (and **install** `docker-compose` if needed).
@@ -107,83 +107,83 @@ In order to do that, follow the steps:
1. Register GitLab Runner from the command line to use `docker` and `privileged`
mode:
- ```bash
- sudo gitlab-runner register -n \
- --url https://gitlab.com/ \
- --registration-token REGISTRATION_TOKEN \
- --executor docker \
- --description "My Docker Runner" \
- --docker-image "docker:stable" \
- --docker-privileged
- ```
-
- The above command will register a new Runner to use the special
- `docker:stable` image which is provided by Docker. **Notice that it's using
- the `privileged` mode to start the build and service containers.** If you
- want to use [docker-in-docker] mode, you always have to use `privileged = true`
- in your Docker containers.
-
- DANGER: **Danger:**
- By enabling `--docker-privileged`, you are effectively disabling all of
- the security mechanisms of containers and exposing your host to privilege
- escalation which can lead to container breakout. For more information, check
- out the official Docker documentation on
- [Runtime privilege and Linux capabilities][docker-cap].
-
- The above command will create a `config.toml` entry similar to this:
-
- ```toml
- [[runners]]
- url = "https://gitlab.com/"
- token = TOKEN
- executor = "docker"
- [runners.docker]
- tls_verify = false
- image = "docker:stable"
- privileged = true
- disable_cache = false
- volumes = ["/cache"]
- [runners.cache]
- Insecure = false
- ```
+ ```bash
+ sudo gitlab-runner register -n \
+ --url https://gitlab.com/ \
+ --registration-token REGISTRATION_TOKEN \
+ --executor docker \
+ --description "My Docker Runner" \
+ --docker-image "docker:stable" \
+ --docker-privileged
+ ```
+
+ The above command will register a new Runner to use the special
+ `docker:stable` image which is provided by Docker. **Notice that it's using
+ the `privileged` mode to start the build and service containers.** If you
+ want to use [docker-in-docker] mode, you always have to use `privileged = true`
+ in your Docker containers.
+
+ DANGER: **Danger:**
+ By enabling `--docker-privileged`, you are effectively disabling all of
+ the security mechanisms of containers and exposing your host to privilege
+ escalation which can lead to container breakout. For more information, check
+ out the official Docker documentation on
+ [Runtime privilege and Linux capabilities][docker-cap].
+
+ The above command will create a `config.toml` entry similar to this:
+
+ ```toml
+ [[runners]]
+ url = "https://gitlab.com/"
+ token = TOKEN
+ executor = "docker"
+ [runners.docker]
+ tls_verify = false
+ image = "docker:stable"
+ privileged = true
+ disable_cache = false
+ volumes = ["/cache"]
+ [runners.cache]
+ Insecure = false
+ ```
1. You can now use `docker` in the build script (note the inclusion of the
`docker:dind` service):
- ```yaml
- image: docker:stable
-
- variables:
- # When using dind service we need to instruct docker, to talk with the
- # daemon started inside of the service. The daemon is available with
- # a network connection instead of the default /var/run/docker.sock socket.
- #
- # The 'docker' hostname is the alias of the service container as described at
- # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
- #
- # Note that if you're using the Kubernetes executor, the variable should be set to
- # tcp://localhost:2375/ because of how the Kubernetes executor connects services
- # to the job container
- # DOCKER_HOST: tcp://localhost:2375/
- #
- # For non-Kubernetes executors, we use tcp://docker:2375/
- DOCKER_HOST: tcp://docker:2375/
- # When using dind, it's wise to use the overlayfs driver for
- # improved performance.
- DOCKER_DRIVER: overlay2
-
- services:
- - docker:dind
-
- before_script:
- - docker info
-
- build:
- stage: build
- script:
- - docker build -t my-docker-image .
- - docker run my-docker-image /script/to/run/tests
- ```
+ ```yaml
+ image: docker:stable
+
+ variables:
+ # When using dind service we need to instruct docker, to talk with the
+ # daemon started inside of the service. The daemon is available with
+ # a network connection instead of the default /var/run/docker.sock socket.
+ #
+ # The 'docker' hostname is the alias of the service container as described at
+ # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
+ #
+ # Note that if you're using the Kubernetes executor, the variable should be set to
+ # tcp://localhost:2375/ because of how the Kubernetes executor connects services
+ # to the job container
+ # DOCKER_HOST: tcp://localhost:2375/
+ #
+ # For non-Kubernetes executors, we use tcp://docker:2375/
+ DOCKER_HOST: tcp://docker:2375/
+ # When using dind, it's wise to use the overlayfs driver for
+ # improved performance.
+ DOCKER_DRIVER: overlay2
+
+ services:
+ - docker:dind
+
+ before_script:
+ - docker info
+
+ build:
+ stage: build
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+ ```
Docker-in-Docker works well, and is the recommended configuration, but it is
not without its own challenges:
@@ -202,14 +202,14 @@ not without its own challenges:
and use it as your mount point (for a more thorough explanation, check [issue
#41227](https://gitlab.com/gitlab-org/gitlab-ce/issues/41227)):
- ```yaml
- variables:
- MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt
+ ```yaml
+ variables:
+ MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt
- script:
- - mkdir -p "$MOUNT_POINT"
- - docker run -v "$MOUNT_POINT:/mnt" my-docker-image
- ```
+ script:
+ - mkdir -p "$MOUNT_POINT"
+ - docker run -v "$MOUNT_POINT:/mnt" my-docker-image
+ ```
An example project using this approach can be found here: <https://gitlab.com/gitlab-examples/docker>.
@@ -230,54 +230,54 @@ In order to do that, follow the steps:
1. Register GitLab Runner from the command line to use `docker` and share `/var/run/docker.sock`:
- ```bash
- sudo gitlab-runner register -n \
- --url https://gitlab.com/ \
- --registration-token REGISTRATION_TOKEN \
- --executor docker \
- --description "My Docker Runner" \
- --docker-image "docker:stable" \
- --docker-volumes /var/run/docker.sock:/var/run/docker.sock
- ```
-
- The above command will register a new Runner to use the special
- `docker:stable` image which is provided by Docker. **Notice that it's using
- the Docker daemon of the Runner itself, and any containers spawned by docker
- commands will be siblings of the Runner rather than children of the runner.**
- This may have complications and limitations that are unsuitable for your workflow.
-
- The above command will create a `config.toml` entry similar to this:
-
- ```toml
- [[runners]]
- url = "https://gitlab.com/"
- token = REGISTRATION_TOKEN
- executor = "docker"
- [runners.docker]
- tls_verify = false
- image = "docker:stable"
- privileged = false
- disable_cache = false
- volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
- [runners.cache]
- Insecure = false
- ```
+ ```bash
+ sudo gitlab-runner register -n \
+ --url https://gitlab.com/ \
+ --registration-token REGISTRATION_TOKEN \
+ --executor docker \
+ --description "My Docker Runner" \
+ --docker-image "docker:stable" \
+ --docker-volumes /var/run/docker.sock:/var/run/docker.sock
+ ```
+
+ The above command will register a new Runner to use the special
+ `docker:stable` image which is provided by Docker. **Notice that it's using
+ the Docker daemon of the Runner itself, and any containers spawned by docker
+ commands will be siblings of the Runner rather than children of the runner.**
+ This may have complications and limitations that are unsuitable for your workflow.
+
+ The above command will create a `config.toml` entry similar to this:
+
+ ```toml
+ [[runners]]
+ url = "https://gitlab.com/"
+ token = REGISTRATION_TOKEN
+ executor = "docker"
+ [runners.docker]
+ tls_verify = false
+ image = "docker:stable"
+ privileged = false
+ disable_cache = false
+ volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
+ [runners.cache]
+ Insecure = false
+ ```
1. You can now use `docker` in the build script (note that you don't need to
include the `docker:dind` service as when using the Docker in Docker executor):
- ```yaml
- image: docker:stable
+ ```yaml
+ image: docker:stable
- before_script:
- - docker info
+ before_script:
+ - docker info
- build:
- stage: build
- script:
- - docker build -t my-docker-image .
- - docker run my-docker-image /script/to/run/tests
- ```
+ build:
+ stage: build
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+ ```
While the above method avoids using Docker in privileged mode, you should be
aware of the following implications:
@@ -293,9 +293,9 @@ aware of the following implications:
work as expected since volume mounting is done in the context of the host
machine, not the build container. For example:
- ```sh
- docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
- ```
+ ```sh
+ docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
+ ```
## Making docker-in-docker builds faster with Docker layer caching
@@ -366,23 +366,23 @@ which can be avoided if a different driver is used, for example `overlay2`.
1. Make sure a recent kernel is used, preferably `>= 4.2`.
1. Check whether the `overlay` module is loaded:
- ```sh
- sudo lsmod | grep overlay
- ```
+ ```sh
+ sudo lsmod | grep overlay
+ ```
- If you see no result, then it isn't loaded. To load it use:
+ If you see no result, then it isn't loaded. To load it use:
- ```sh
- sudo modprobe overlay
- ```
+ ```sh
+ sudo modprobe overlay
+ ```
- If everything went fine, you need to make sure module is loaded on reboot.
- On Ubuntu systems, this is done by editing `/etc/modules`. Just add the
- following line into it:
+ If everything went fine, you need to make sure module is loaded on reboot.
+ On Ubuntu systems, this is done by editing `/etc/modules`. Just add the
+ following line into it:
- ```text
- overlay
- ```
+ ```text
+ overlay
+ ```
### Use driver per project
@@ -450,9 +450,9 @@ For all projects, mostly suitable for public ones:
your Docker images and has read/write access to the Registry. This is ephemeral,
so it's only valid for one job. You can use the following example as-is:
- ```sh
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- ```
+ ```sh
+ docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ ```
For private and internal projects:
@@ -465,9 +465,9 @@ For private and internal projects:
Replace the `<username>` and `<access_token>` in the following example:
- ```sh
- docker login -u <username> -p <access_token> $CI_REGISTRY
- ```
+ ```sh
+ docker login -u <username> -p <access_token> $CI_REGISTRY
+ ```
- **Using the GitLab Deploy Token**: You can create and use a
[special deploy token](../../user/project/deploy_tokens/index.md#gitlab-deploy-token)
@@ -475,9 +475,9 @@ For private and internal projects:
Once created, you can use the special environment variables, and GitLab CI/CD
will fill them in for you. You can use the following example as-is:
- ```sh
- docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
- ```
+ ```sh
+ docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
+ ```
### Container Registry examples
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index f3896c5232c..d5056568dff 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -305,25 +305,25 @@ For example, the following two definitions are equal:
1. Using a string as an option to `image` and `services`:
- ```yaml
- image: "registry.example.com/my/image:latest"
+ ```yaml
+ image: "registry.example.com/my/image:latest"
- services:
- - postgresql:9.4
- - redis:latest
- ```
+ services:
+ - postgresql:9.4
+ - redis:latest
+ ```
1. Using a map as an option to `image` and `services`. The use of `image:name` is
required:
- ```yaml
- image:
- name: "registry.example.com/my/image:latest"
+ ```yaml
+ image:
+ name: "registry.example.com/my/image:latest"
- services:
- - name: postgresql:9.4
- - name: redis:latest
- ```
+ services:
+ - name: postgresql:9.4
+ - name: redis:latest
+ ```
### Available settings for `image`
@@ -526,6 +526,7 @@ it's provided as an environment variable. This is because GitLab Runnner uses **
runtime.
### Using statically-defined credentials
+
There are two approaches that you can take in order to access a
private registry. Both require setting the environment variable
`DOCKER_AUTH_CONFIG` with appropriate authentication info.
@@ -555,18 +556,18 @@ There are two ways to determine the value of `DOCKER_AUTH_CONFIG`:
- **First way -** Do a `docker login` on your local machine:
- ```bash
- docker login registry.example.com:5000 --username my_username --password my_password
- ```
+ ```bash
+ docker login registry.example.com:5000 --username my_username --password my_password
+ ```
- Then copy the content of `~/.docker/config.json`.
+ Then copy the content of `~/.docker/config.json`.
- If you don't need access to the registry from your computer, you
- can do a `docker logout`:
+ If you don't need access to the registry from your computer, you
+ can do a `docker logout`:
- ```bash
- docker logout registry.example.com:5000
- ```
+ ```bash
+ docker logout registry.example.com:5000
+ ```
- **Second way -** In some setups, it's possible that Docker client
will use the available system keystore to store the result of `docker
@@ -575,12 +576,12 @@ There are two ways to determine the value of `DOCKER_AUTH_CONFIG`:
`${username}:${password}` manually. Open a terminal and execute the
following command:
- ```bash
- echo -n "my_username:my_password" | base64
+ ```bash
+ echo -n "my_username:my_password" | base64
- # Example output to copy
- bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=
- ```
+ # Example output to copy
+ bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=
+ ```
#### Configuring a job
@@ -590,25 +591,25 @@ follow these steps:
1. Create a [variable](../variables/README.md#gitlab-cicd-environment-variables) `DOCKER_AUTH_CONFIG` with the content of the
Docker configuration file as the value:
- ```json
- {
- "auths": {
- "registry.example.com:5000": {
- "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
- }
- }
- }
- ```
+ ```json
+ {
+ "auths": {
+ "registry.example.com:5000": {
+ "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
+ }
+ }
+ }
+ ```
1. You can now use any private image from `registry.example.com:5000` defined in
`image` and/or `services` in your `.gitlab-ci.yml` file:
- ```yaml
- image: registry.example.com:5000/namespace/image:tag
- ```
+ ```yaml
+ image: registry.example.com:5000/namespace/image:tag
+ ```
- In the example above, GitLab Runner will look at `registry.example.com:5000` for the
- image `namespace/image:tag`.
+ In the example above, GitLab Runner will look at `registry.example.com:5000` for the
+ image `namespace/image:tag`.
You can add configuration for as many registries as you want, adding more
registries to the `"auths"` hash as described above.
@@ -637,10 +638,10 @@ To add `DOCKER_AUTH_CONFIG` to a Runner:
1. Modify the Runner's `config.toml` file as follows:
- ```toml
- [[runners]]
- environment = ["DOCKER_AUTH_CONFIG={\"auths\":{\"registry.example.com:5000\":{\"auth\":\"bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=\"}}}"]
- ```
+ ```toml
+ [[runners]]
+ environment = ["DOCKER_AUTH_CONFIG={\"auths\":{\"registry.example.com:5000\":{\"auth\":\"bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=\"}}}"]
+ ```
1. Restart the Runner service.
@@ -662,16 +663,17 @@ To configure credentials store, follow these steps:
Make sure helper program is available in GitLab Runner `$PATH`.
1. Make GitLab Runner use it. There are two ways to accomplish this. Either:
+
- Create a
[variable](../variables/README.md#gitlab-cicd-environment-variables)
`DOCKER_AUTH_CONFIG` with the content of the
- Docker configuration file as the value:
+ Docker configuration file as the value:
- ```json
- {
- "credsStore": "osxkeychain"
- }
- ```
+ ```json
+ {
+ "credsStore": "osxkeychain"
+ }
+ ```
- Or, if you are running self-hosted Runners, add the above JSON to
`${GITLAB_RUNNER_HOME}/.docker/config.json`. GitLab Runner will read this config file
@@ -693,17 +695,18 @@ To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow th
1. Make sure `docker-credential-ecr-login` is available in GitLab Runner's `$PATH`.
1. Make GitLab Runner use it. There are two ways to accomplish this. Either:
+
- Create a [variable](../variables/README.md#gitlab-cicd-environment-variables)
`DOCKER_AUTH_CONFIG` with the content of the
- Docker configuration file as the value:
+ Docker configuration file as the value:
- ```json
- {
- "credHelpers": {
- "aws_account_id.dkr.ecr.region.amazonaws.com": "ecr-login"
- }
- }
- ```
+ ```json
+ {
+ "credHelpers": {
+ "aws_account_id.dkr.ecr.region.amazonaws.com": "ecr-login"
+ }
+ }
+ ```
- Or, if you are running self-hosted Runners,
add the above JSON to `${GITLAB_RUNNER_HOME}/.docker/config.json`.
@@ -713,12 +716,12 @@ To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow th
1. You can now use any private image from `aws_account_id.dkr.ecr.region.amazonaws.com` defined in
`image` and/or `services` in your `.gitlab-ci.yml` file:
- ```yaml
- image: aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest
- ```
+ ```yaml
+ image: aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest
+ ```
- In the example above, GitLab Runner will look at `aws_account_id.dkr.ecr.region.amazonaws.com` for the
- image `private/image:latest`.
+ In the example above, GitLab Runner will look at `aws_account_id.dkr.ecr.region.amazonaws.com` for the
+ image `private/image:latest`.
You can add configuration for as many registries as you want, adding more
registries to the `"credHelpers"` hash as described above.
diff --git a/doc/ci/examples/artifactory_and_gitlab/index.md b/doc/ci/examples/artifactory_and_gitlab/index.md
index c9f700ed190..940c4711132 100644
--- a/doc/ci/examples/artifactory_and_gitlab/index.md
+++ b/doc/ci/examples/artifactory_and_gitlab/index.md
@@ -39,9 +39,10 @@ project:
1. Create a new project by selecting **Import project from โž” Repo by URL**
1. Add the following URL:
- ```
- https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git
- ```
+ ```
+ https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git
+ ```
+
1. Click **Create project**
This application is nothing more than a basic class with a stub for a JUnit based test suite.
@@ -63,15 +64,15 @@ The application is ready to use, but you need some additional steps to deploy it
1. Copy the snippet in the `pom.xml` file for your project, just after the
`dependencies` section. The snippet should look like this:
- ```xml
- <distributionManagement>
- <repository>
- <id>central</id>
- <name>83d43b5afeb5-releases</name>
- <url>${env.MAVEN_REPO_URL}/libs-release-local</url>
- </repository>
- </distributionManagement>
- ```
+ ```xml
+ <distributionManagement>
+ <repository>
+ <id>central</id>
+ <name>83d43b5afeb5-releases</name>
+ <url>${env.MAVEN_REPO_URL}/libs-release-local</url>
+ </repository>
+ </distributionManagement>
+ ```
Another step you need to do before you can deploy the dependency to Artifactory
is to configure the authentication data. It is a simple task, but Maven requires
@@ -86,18 +87,18 @@ parameter in `.gitlab-ci.yml` to use the custom location instead of the default
1. Create a file called `settings.xml` in the `.m2` folder
1. Copy the following content into a `settings.xml` file:
- ```xml
- <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"
- xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <servers>
- <server>
- <id>central</id>
- <username>${env.MAVEN_REPO_USER}</username>
- <password>${env.MAVEN_REPO_PASS}</password>
- </server>
- </servers>
- </settings>
- ```
+ ```xml
+ <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"
+ xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <servers>
+ <server>
+ <id>central</id>
+ <username>${env.MAVEN_REPO_USER}</username>
+ <password>${env.MAVEN_REPO_PASS}</password>
+ </server>
+ </servers>
+ </settings>
+ ```
Username and password will be replaced by the correct values using variables.
@@ -187,9 +188,10 @@ We'll use again a Maven app that can be cloned from our example project:
1. Create a new project by selecting **Import project from โž” Repo by URL**
1. Add the following URL:
- ```
- https://gitlab.com/gitlab-examples/maven/simple-maven-app.git
- ```
+ ```
+ https://gitlab.com/gitlab-examples/maven/simple-maven-app.git
+ ```
+
1. Click **Create project**
This one is a simple app as well. If you look at the `src/main/java/com/example/app/App.java`
@@ -204,13 +206,13 @@ Since Maven doesn't know how to resolve the dependency, you need to modify the c
1. Copy the snippet in the `dependencies` section of the `pom.xml` file.
The snippet should look like this:
- ```xml
- <dependency>
- <groupId>com.example.dep</groupId>
- <artifactId>simple-maven-dep</artifactId>
- <version>1.0</version>
- </dependency>
- ```
+ ```xml
+ <dependency>
+ <groupId>com.example.dep</groupId>
+ <artifactId>simple-maven-dep</artifactId>
+ <version>1.0</version>
+ </dependency>
+ ```
### Configure the Artifactory repository location
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
index a5fed00972f..0e595e1a0be 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
@@ -188,28 +188,27 @@ when running our Phoenix in our `localhost`.
- Open `hello_gitlab_ci/config/test.exs` on your favorite code editor
- Go to **Configure your database** session and edit the block to include `System.get_env`:
- ```elixir
- # Configure your database
- config :hello_gitlab_ci, HelloGitlabCi.Repo,
- adapter: Ecto.Adapters.Postgres,
- username: System.get_env("POSTGRES_USER") || "postgres",
- password: System.get_env("POSTGRES_PASSWORD") || "postgres",
- database: System.get_env("POSTGRES_DB") || "hello_gitlab_ci_test",
- hostname: System.get_env("POSTGRES_HOST") || "localhost",
- pool: Ecto.Adapters.SQL.Sandbox
- ```
-
- We'll need these system variables later on.
+ ```elixir
+ # Configure your database
+ config :hello_gitlab_ci, HelloGitlabCi.Repo,
+ adapter: Ecto.Adapters.Postgres,
+ username: System.get_env("POSTGRES_USER") || "postgres",
+ password: System.get_env("POSTGRES_PASSWORD") || "postgres",
+ database: System.get_env("POSTGRES_DB") || "hello_gitlab_ci_test",
+ hostname: System.get_env("POSTGRES_HOST") || "localhost",
+ pool: Ecto.Adapters.SQL.Sandbox
+ ```
+
+ We'll need these system variables later on.
- Create an empty file named `.gitkeep` into `hello_gitlab_ci/priv/repo/migrations`
- As our project is still fresh, we don't have any data on our database, so, the `migrations`
-directory will be empty.
- Without `.gitkeep`, git will not upload this empty directory and we'll got an error when running our
-test on GitLab.
+ As our project is still fresh, we don't have any data on our database, so, the `migrations`
+ directory will be empty.
+ Without `.gitkeep`, git will not upload this empty directory and we'll got an error when running our
+ test on GitLab.
- > **Note:**
- If we add a folder via the GitLab UI, GitLab itself will add the `.gitkeep` to that new dir.
+ > **Note:** If we add a folder via the GitLab UI, GitLab itself will add the `.gitkeep` to that new dir.
Now, let's run a local test and see if everything we did didn't break anything.
@@ -248,64 +247,64 @@ project.
- The fastest and easiest way to do this, is to click on **Set up CI** on project's main page:
- ![Set up CI](img/setup-ci.png)
+ ![Set up CI](img/setup-ci.png)
- On next screen, we can select a template ready to go. Click on **Apply a GitLab CI/CD Yaml
template** and select **Elixir**:
- ![Select template](img/select-template.png)
+ ![Select template](img/select-template.png)
- This template file tells GitLab CI/CD about what we wish to do every time a new commit is made.
- However, we have to adapt it to run a Phoenix app.
+ This template file tells GitLab CI/CD about what we wish to do every time a new commit is made.
+ However, we have to adapt it to run a Phoenix app.
- The first line tells GitLab what Docker image will be used.
- Remember when we learn about Runners, the isolated virtual machine where GitLab CI/CD build and test
- our application? This virtual machine must have all dependencies to run our application. This is
- where a Docker image is needed. The correct image will provide the entire system for us.
+ Remember when we learn about Runners, the isolated virtual machine where GitLab CI/CD build and test
+ our application? This virtual machine must have all dependencies to run our application. This is
+ where a Docker image is needed. The correct image will provide the entire system for us.
- As a suggestion, you can use [trenpixster's elixir image][docker-image], which already has all
- dependencies for Phoenix installed, such as Elixir, Erlang, NodeJS and PostgreSQL:
+ As a suggestion, you can use [trenpixster's elixir image][docker-image], which already has all
+ dependencies for Phoenix installed, such as Elixir, Erlang, NodeJS and PostgreSQL:
- ```yml
- image: trenpixster/elixir:latest
- ```
+ ```yml
+ image: trenpixster/elixir:latest
+ ```
- At `services` session, we'll only use `postgres`, so we'll delete `mysql` and `redis` lines:
- ```yml
- services:
- - postgres:latest
- ```
+ ```yml
+ services:
+ - postgres:latest
+ ```
- Now, we'll create a new entry called `variables`, before `before_script` session:
- ```yml
- variables:
- POSTGRES_DB: hello_gitlab_ci_test
- POSTGRES_HOST: postgres
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: "postgres"
- MIX_ENV: "test"
- ```
+ ```yml
+ variables:
+ POSTGRES_DB: hello_gitlab_ci_test
+ POSTGRES_HOST: postgres
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: "postgres"
+ MIX_ENV: "test"
+ ```
- Here, we are setting up the values for GitLab CI/CD authenticate into PostgreSQL, as we did on
- `config/test.exs` earlier.
+ Here, we are setting up the values for GitLab CI/CD authenticate into PostgreSQL, as we did on
+ `config/test.exs` earlier.
- In `before_script` session, we'll add some commands to prepare everything to the test:
- ```yml
- before_script:
- - apt-get update && apt-get -y install postgresql-client
- - mix local.hex --force
- - mix deps.get --only test
- - mix ecto.create
- - mix ecto.migrate
- ```
-
- It's important to install `postgresql-client` to let GitLab CI/CD access PostgreSQL and create our
- database with the login information provided earlier. More important is to respect the indentation,
- to avoid syntax errors when running the build.
+ ```yml
+ before_script:
+ - apt-get update && apt-get -y install postgresql-client
+ - mix local.hex --force
+ - mix deps.get --only test
+ - mix ecto.create
+ - mix ecto.migrate
+ ```
+
+ It's important to install `postgresql-client` to let GitLab CI/CD access PostgreSQL and create our
+ database with the login information provided earlier. More important is to respect the indentation,
+ to avoid syntax errors when running the build.
- And finally, we'll let `mix` session intact.
diff --git a/doc/ci/ssh_keys/README.md b/doc/ci/ssh_keys/README.md
index 69591ed605c..d9f022a7125 100644
--- a/doc/ci/ssh_keys/README.md
+++ b/doc/ci/ssh_keys/README.md
@@ -57,44 +57,44 @@ to access it. This is where an SSH key pair comes in handy.
1. Modify your `.gitlab-ci.yml` with a `before_script` action. In the following
example, a Debian based image is assumed. Edit to your needs:
- ```yaml
- before_script:
- ##
- ## Install ssh-agent if not already installed, it is required by Docker.
- ## (change apt-get to yum if you use an RPM-based image)
- ##
- - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
-
- ##
- ## Run ssh-agent (inside the build environment)
- ##
- - eval $(ssh-agent -s)
-
- ##
- ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
- ## We're using tr to fix line endings which makes ed25519 keys work
- ## without extra base64 encoding.
- ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
- ##
- - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
-
- ##
- ## Create the SSH directory and give it the right permissions
- ##
- - mkdir -p ~/.ssh
- - chmod 700 ~/.ssh
-
- ##
- ## Optionally, if you will be using any Git commands, set the user name and
- ## and email.
- ##
- #- git config --global user.email "user@example.com"
- #- git config --global user.name "User name"
- ```
-
- NOTE: **Note:**
- The [`before_script`](../yaml/README.md#before_script-and-after_script) can be set globally
- or per-job.
+ ```yaml
+ before_script:
+ ##
+ ## Install ssh-agent if not already installed, it is required by Docker.
+ ## (change apt-get to yum if you use an RPM-based image)
+ ##
+ - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
+
+ ##
+ ## Run ssh-agent (inside the build environment)
+ ##
+ - eval $(ssh-agent -s)
+
+ ##
+ ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
+ ## We're using tr to fix line endings which makes ed25519 keys work
+ ## without extra base64 encoding.
+ ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
+ ##
+ - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
+
+ ##
+ ## Create the SSH directory and give it the right permissions
+ ##
+ - mkdir -p ~/.ssh
+ - chmod 700 ~/.ssh
+
+ ##
+ ## Optionally, if you will be using any Git commands, set the user name and
+ ## and email.
+ ##
+ #- git config --global user.email "user@example.com"
+ #- git config --global user.name "User name"
+ ```
+
+ NOTE: **Note:**
+ The [`before_script`](../yaml/README.md#before_script-and-after_script) can be set globally
+ or per-job.
1. Make sure the private server's [SSH host keys are verified](#verifying-the-ssh-host-keys).
@@ -118,9 +118,9 @@ on, and use that key for all projects that are run on this machine.
1. Then from the terminal login as the `gitlab-runner` user:
- ```
- sudo su - gitlab-runner
- ```
+ ```
+ sudo su - gitlab-runner
+ ```
1. Generate the SSH key pair as described in the instructions to
[generate an SSH key](../../ssh/README.md#generating-a-new-ssh-key-pair).
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 4d6ca8cff6d..c48817a5e30 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -370,8 +370,11 @@ variables take precedence over those defined in `.gitlab-ci.yml`.
## Unsupported variables
There are cases where some variables cannot be used in the context of a
-`.gitlab-ci.yml` definition (for example under `script`). Read more
-about which variables are [not supported](where_variables_can_be_used.md).
+`.gitlab-ci.yml` definition (for example under `script`). Read more about which variables are [not supported](where_variables_can_be_used.md).
+
+## Where variables can be used
+
+Click [here](where_variables_can_be_used.md) for a section that describes where and how the different types of variables can be used.
## Advanced use
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 201047b70b9..a6051e87366 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -2468,20 +2468,20 @@ There are three possible values: `none`, `normal`, and `recursive`:
- `normal` means that only the top-level submodules will be included. It is
equivalent to:
- ```
- git submodule sync
- git submodule update --init
- ```
+ ```
+ git submodule sync
+ git submodule update --init
+ ```
- `recursive` means that all submodules (including submodules of submodules)
will be included. This feature needs Git v1.8.1 and later. When using a
GitLab Runner with an executor not based on Docker, make sure the Git version
meets that requirement. It is equivalent to:
- ```
- git submodule sync --recursive
- git submodule update --init --recursive
- ```
+ ```
+ git submodule sync --recursive
+ git submodule update --init --recursive
+ ```
Note that for this feature to work correctly, the submodules must be configured
(in `.gitmodules`) with either:
diff --git a/doc/development/fe_guide/event_tracking.md b/doc/development/fe_guide/event_tracking.md
index 716f6ad7f92..1e6287d8f6d 100644
--- a/doc/development/fe_guide/event_tracking.md
+++ b/doc/development/fe_guide/event_tracking.md
@@ -1,79 +1,76 @@
# Event Tracking
-We use [Snowplow](https://github.com/snowplow/snowplow) for tracking custom events (available in GitLab [Enterprise Edition](https://about.gitlab.com/pricing/) only).
+We use a tracking interface that wraps up [Snowplow](https://github.com/snowplow/snowplow) for tracking custom events. Snowplow implements page tracking, but also exposes custom event tracking.
-## Generic tracking function
-
-In addition to Snowplow's built-in method for tracking page views, we use a generic tracking function which enables us to selectively apply listeners to events.
-
-The generic tracking function can be imported in EE-specific JS files as follows:
+The tracking interface can be imported in JS files as follows:
```javascript
-import { trackEvent } from `ee/stats`;
+import Tracking from `~/tracking`;
```
-This gives the user access to the `trackEvent` method, which takes the following parameters:
+## Tracking in HAML or Vue templates
-| parameter | type | description | required |
-| ---------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
-| `category` | string | Describes the page that you're capturing click events on. Unless infeasible, please use the Rails page attribute `document.body.dataset.page` by default. | true |
-| `eventName` | string | Describes the action the user is taking. The first word should always describe the action. For example, clicks should be `click` and activations should be `activate`. Use underscores to describe what was acted on. For example, activating a form field would be `activate_form_input`. Clicking on a dropdown is `click_dropdown`. | true |
-| `additionalData` | object | Additional data such as `label`, `property`, and `value` as described [in our Feature Instrumentation taxonomy](https://about.gitlab.com/handbook/product/feature-instrumentation/#taxonomy). | false |
+To avoid having to do create a bunch of custom javascript event handlers, when working within HAML or Vue templates, we can add `data-track-*` attributes to elements of interest. This way, all elements that have a `data-track-event` attribute to automatically have event tracking bound.
-Read more about instrumentation and the taxonomy in the [Product Handbook](https://about.gitlab.com/handbook/product/feature-instrumentation).
-
-### Tracking in `.js` and `.vue` files
+Below is an example of `data-track-*` attributes assigned to a button in HAML:
-The most simple use case is to add tracking programmatically to an event of interest in Javascript.
+```haml
+%button.btn{ data: { track_event: "click_button", track_label: "template_preview", track_property: "my-template", track_value: "" } }
+```
-The following example demonstrates how to track a click on a button in Javascript by calling the `trackEvent` method explicitly:
+We can then setup tracking for large sections of a page, or an entire page by telling the Tracking interface to bind to it.
```javascript
-import { trackEvent } from `ee/stats`;
+import Tracking from '~/tracking';
-trackEvent('dashboard:projects:index', 'click_button', {
- label: 'create_from_template',
- property: 'template_preview',
- value: 'rails',
+// for the entire document
+new Tracking().bind();
+
+// for a container element
+document.addEventListener('DOMContentLoaded', () => {
+ new Tracking('my_category').bind(document.getElementById('my-container'));
});
+
```
-### Tracking in HAML templates
+When you instantiate a Tracking instance you can provide a category. If none is provided, `document.body.dataset.page` will be used. When you bind the Tracking instance you can provide an element. If no element is provided to bind to, the `document` is assumed.
-Sometimes we want to track clicks for multiple elements on a page. Creating event handlers for all elements could soon turn into a tedious task.
+Below is a list of supported `data-track-*` attributes:
-There's a more convenient solution to this problem. When working with HAML templates, we can add `data-track-*` attributes to elements of interest. This way, all elements that have both `data-track-label` and `data-track-event` attributes assigned get marked for event tracking. All we have to do is call the `bindTrackableContainer` method on a container which allows for better scoping.
+| attribute | required | description |
+|:----------------------|:---------|:------------|
+| `data-track-event` | true | Action the user is taking. Clicks should be `click` and activations should be `activate`, so for example, focusing a form field would be `activate_form_input`, and clicking a button would be `click_button`. |
+| `data-track-label` | false | The `label` as described [in our Feature Instrumentation taxonomy](https://about.gitlab.com/handbook/product/feature-instrumentation/#taxonomy) |
+| `data-track-property` | false | The `property` as described [in our Feature Instrumentation taxonomy](https://about.gitlab.com/handbook/product/feature-instrumentation/#taxonomy)
+| `data-track-value` | false | The `value` as described [in our Feature Instrumentation taxonomy](https://about.gitlab.com/handbook/product/feature-instrumentation/#taxonomy). If omitted, this will be the elements `value` property or an empty string. For checkboxes, the default value will be the element's checked attribute or `false` when unchecked.
-Below is an example of `data-track-*` attributes assigned to a button in HAML:
-```ruby
-%button.btn{ data: { track_label: "template_preview", track_property: "my-template", track_event: "click_button", track_value: "" } }
-```
-
-By calling `bindTrackableContainer('.my-container')`, click handlers get bound to all elements located in `.my-container` provided that they have the necessary `data-track-*` attributes assigned to them.
+## Tracking in raw Javascript
-```javascript
-import Stats from 'ee/stats';
+Custom events can be tracked by directly calling the `Tracking.event` static function, which accepts the following arguments:
-document.addEventListener('DOMContentLoaded', () => {
- Stats.bindTrackableContainer('.my-container', 'category');
-});
-```
+| argument | type | default value | description |
+|:-----------|:-------|:---------------------------|:------------|
+| `category` | string | document.body.dataset.page | Page or subsection of a page that events are being captured within. |
+| `event` | string | 'generic' | Action the user is taking. Clicks should be `click` and activations should be `activate`, so for example, focusing a form field would be `activate_form_input`, and clicking a button would be `click_button`. |
+| `data` | object | {} | Additional data such as `label`, `property`, and `value` as described [in our Feature Instrumentation taxonomy](https://about.gitlab.com/handbook/product/feature-instrumentation/#taxonomy). These will be set as empty strings if you don't provide them. |
-The second parameter in `bindTrackableContainer` is optional. If omitted, the value of `document.body.dataset.page` will be used as category instead.
+Tracking can be programmatically added to an event of interest in Javascript, and the following example demonstrates tracking a click on a button by calling `Tracking.event` manually.
-Below is a list of supported `data-track-*` attributes:
+```javascript
+import Tracking from `~/tracking`;
-| attribute | description | required |
-| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
-| `data-track-label` | The `label` in `trackEvent` | true |
-| `data-track-event` | The `eventName` in `trackEvent` | true |
-| `data-track-property` | The `property` in `trackEvent`. If omitted, an empty string will be used as a default value. | false |
-| `data-track-value` | The `value` in `trackEvent`. If omitted, this will be `target.value` or empty string. For checkboxes, the default value being tracked will be the element's checked attribute if `data-track-value` is omitted. | false |
+document.getElementById('my_button').addEventListener('click', () => {
+ Tracking.event('dashboard:projects:index', 'click_button', {
+ label: 'create_from_template',
+ property: 'template_preview',
+ value: 'rails',
+ });
+})
+```
-Since Snowplow is an Enterprise Edition feature, it's necessary to create a CE backport when adding `data-track-*` attributes to HAML templates in most cases.
-## Testing
+## Toggling tracking on or off
Snowplow can be enabled by navigating to:
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
index 96761622cfe..d07a7045390 100644
--- a/doc/development/testing_guide/review_apps.md
+++ b/doc/development/testing_guide/review_apps.md
@@ -115,6 +115,28 @@ On every [pipeline][gitlab-pipeline] in the `qa` stage, the
browser performance testing using a
[Sitespeed.io Container](../../user/project/merge_requests/browser_performance_testing.md).
+## Cluster configuration
+
+### Node pools
+
+Both `review-apps-ce` and `review-apps-ee` clusters are currently set up with
+two node pools:
+
+- a node pool of non-preemptible `n1-standard-2` (2 vCPU, 7.5 GB memory) nodes
+ dedicated to the `tiller` deployment (see below) with a single node.
+- a node pool of preemptible `n1-standard-2` (2 vCPU, 7.5 GB memory) nodes,
+ with a minimum of 1 node and a maximum of 250 nodes.
+
+### Helm/Tiller
+
+The `tiller` deployment (the Helm server) is deployed to a dedicated node pool
+that has the `app=helm` label and a specific
+[taint](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/)
+to prevent other pods from being scheduled on this node pool.
+
+This is to ensure Tiller isn't affected by "noisy" neighbors that could put
+their node under pressure.
+
## How to:
### Log into my Review App
@@ -241,15 +263,6 @@ thousands of unused Docker images.**
CNG-mirror project to store these Docker images so that we can just wipe out
the registry at some point, and use a new fresh, empty one.
-**How big are the Kubernetes clusters (`review-apps-ce` and `review-apps-ee`)?**
-
- > The clusters are currently set up with a single pool of preemptible nodes,
- with a minimum of 1 node and a maximum of 500 nodes.
-
-**What are the machine running on the cluster?**
-
- > We're currently using `n1-standard-1` (1 vCPU, 3.75 GB memory) machines.
-
**How do we secure this from abuse? Apps are open to the world so we need to
find a way to limit it to only us.**
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 46ee980841b..a12edef4e41 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -938,7 +938,7 @@ To use GitLab with Puma:
cd /home/git/gitlab
# Copy config file for the web server
- sudo -u git -H config/puma.rb.example config/puma.rb
+ sudo -u git -H cp config/puma.rb.example config/puma.rb
```
1. Edit the system `init.d` script to use `EXPERIMENTAL_PUMA=1` flag. If you have `/etc/default/gitlab`, then you should edit it instead.
diff --git a/doc/security/README.md b/doc/security/README.md
index c48d5bc2065..5d498ac7602 100644
--- a/doc/security/README.md
+++ b/doc/security/README.md
@@ -7,7 +7,7 @@ type: index
- [Password length limits](password_length_limits.md)
- [Restrict SSH key technologies and minimum length](ssh_keys_restrictions.md)
-- [Rack attack](rack_attack.md)
+- [Rate limits](rate_limits.md)
- [Webhooks and insecure internal web services](webhooks.md)
- [Information exclusivity](information_exclusivity.md)
- [Reset your root password](reset_root_password.md)
diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md
index 1e5678ec47c..c772f783f71 100644
--- a/doc/security/rack_attack.md
+++ b/doc/security/rack_attack.md
@@ -2,7 +2,9 @@
type: reference, howto
---
-# Rack Attack
+# Rack Attack initializer
+
+## Overview
[Rack Attack](https://github.com/kickstarter/rack-attack), also known as Rack::Attack, is a Ruby gem
that is meant to protect GitLab with the ability to customize throttling and
@@ -14,19 +16,72 @@ If you find throttling is not enough to protect you against abusive clients,
Rack Attack offers IP whitelisting, blacklisting, Fail2ban style filtering, and
tracking.
-**Note:** Starting with 11.2, Rack Attack is disabled by default. To continue
-using Rack Attack, please enable it by [configuring `gitlab.rb` as described in Settings](#settings).
+For more information on how to use these options see the [Rack Attack README](https://github.com/kickstarter/rack-attack/blob/master/README.md).
+
+NOTE: **Note:** See
+[User and IP rate limits](../user/admin_area/settings/user_and_ip_rate_limits.md)
+for simpler throttles that are configured in UI.
+
+NOTE: **Note:** Starting with 11.2, Rack Attack is disabled by default. If your
+instance is not exposed to the public internet, it is recommended that you leave
+Rack Attack disabled.
+
+## Behavior
+
+If set up as described in the [Settings](#settings) section below, two behaviors
+will be enabled:
+
+- Protected paths will be throttled
+- Failed authentications for Git and container registry requests will trigger a temporary IP ban
+
+### Protected paths throttle
+
+GitLab responds with HTTP status code 429 to POST requests at protected paths
+over 10 requests per minute per IP address.
+
+By default, protected paths are:
+
+```ruby
+default['gitlab']['gitlab-rails']['rack_attack_protected_paths'] = [
+ '/users/password',
+ '/users/sign_in',
+ '/api/#{API::API.version}/session.json',
+ '/api/#{API::API.version}/session',
+ '/users',
+ '/users/confirmation',
+ '/unsubscribes/',
+ '/import/github/personal_access_token'
+]
+```
+
+This header is included in responses to blocked requests:
+
+```
+Retry-After: 60
+```
+
+For example, the following are limited to a maximum 10 requests per minute:
+
+- user sign-in
+- user sign-up (if enabled)
+- user password reset
+
+After trying for 10 times, the client will
+have to wait a minute before to be able to try again.
+
+### Git and container registry failed authentication ban
+
+GitLab responds with HTTP status code 403 for 1 hour, if 30 failed
+authentication requests were received in a 3-minute period from a single IP address.
-By default, user sign-in, user sign-up (if enabled), and user password reset is
-limited to 6 requests per minute. After trying for 6 times, the client will
-have to wait for the next minute to be able to try again.
+This applies only to Git requests and container registry (`/jwt/auth`) requests
+(combined).
-If you installed or upgraded GitLab by following the [official guides](../install/README.md),
-Rack Attack should be disabled by default. If your instance is not exposed to any incoming
-connections, it is recommended that you leave Rack Attack disabled.
+This limit is reset by requests that authenticate successfully. For example, 29
+failed authentication requests followed by 1 successful request, followed by 29
+more failed authentication requests would not trigger a ban.
-For more information on how to use these options check out
-[rack-attack README](https://github.com/kickstarter/rack-attack/blob/master/README.md).
+No response headers are provided.
## Settings
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
new file mode 100644
index 00000000000..0e5bdcd9c79
--- /dev/null
+++ b/doc/security/rate_limits.md
@@ -0,0 +1,32 @@
+---
+type: reference, howto
+---
+
+# Rate limits
+
+NOTE: **Note:**
+For GitLab.com, please see
+[GitLab.com-specific rate limits](../user/gitlab_com/index.md#gitlabcom-specific-rate-limits).
+
+Rate limiting is a common technique used to improve the security and durability
+of a web application.
+
+For example, a simple script can make thousands of web requests per second.
+Whether malicious, apathetic, or just a bug, your application and infrastructure
+may not be able to cope with the load. For more details, see
+[Denial-of-service attack](https://en.wikipedia.org/wiki/Denial-of-service_attack).
+Most cases can be mitigated by limiting the rate of requests from a single IP address.
+
+Most [brute-force attacks](https://en.wikipedia.org/wiki/Brute-force_attack) are
+similarly mitigated by a rate limit.
+
+## Admin Area settings
+
+See
+[User and IP rate limits](../user/admin_area/settings/user_and_ip_rate_limits.md).
+
+## Rack Attack initializer
+
+This method of rate limiting is cumbersome, but has some advantages. It allows
+throttling of specific paths, and is also integrated into Git and container
+registry requests. See [Rack Attack initializer](rack_attack.md).
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 1687a3aee72..63a72f8f193 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -1069,6 +1069,12 @@ Container Registry. **Restarting a pod, scaling a service, or other actions whic
require on-going access to the registry may fail**. On-going secure access is
planned for a subsequent release.
+### Private registry support
+
+There is no documented way of using private container registry with Auto DevOps.
+We strongly advise using GitLab Container Registry with Auto DevOps in order to
+simplify configuration and prevent any unforeseen issues.
+
## Troubleshooting
- Auto Build and Auto Test may fail in detecting your language/framework. There
diff --git a/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png b/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png
new file mode 100644
index 00000000000..2bd85a2fd96
--- /dev/null
+++ b/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png
Binary files differ
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 5427d04cd7d..2a12614e325 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -18,6 +18,7 @@ include:
- [Third party offers](third_party_offers.md)
- [Usage statistics](usage_statistics.md)
- [Visibility and access controls](visibility_and_access_controls.md)
+- [User and IP rate limits](user_and_ip_rate_limits.md)
- [Custom templates repository](instance_template_repository.md) **(PREMIUM)**
NOTE: **Note:**
diff --git a/doc/user/admin_area/settings/user_and_ip_rate_limits.md b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
new file mode 100644
index 00000000000..e3a495750f2
--- /dev/null
+++ b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
@@ -0,0 +1,32 @@
+---
+type: reference
+---
+
+# User and IP rate limits
+
+Rate limiting is a common technique used to improve the security and durability
+of a web application. For more details, see
+[Rate limits](../../../security/rate_limits.md).
+
+The following limits can be enforced in **Admin Area > Network > User and
+IP rate limits**:
+
+- Unauthenticated requests
+- Authenticated API requests
+- Authenticated web requests
+
+These limits are disabled by default.
+
+![user-and-ip-rate-limits](img/user_and_ip_rate_limits.png)
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 88e2d1ef22b..fa84f995e58 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -7,6 +7,11 @@ type: reference, howto
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/4348)
in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
+NOTE: **4 of the top 6 attacks were application based.**
+Download our whitepaper,
+["A Seismic Shift in Application Security"](https://about.gitlab.com/resources/whitepaper-seismic-shift-application-security/)
+to learn how to protect your organization.
+
Running [static checks](../sast/index.md) on your code is the first step to detect
vulnerabilities that can put the security of your code at risk. Yet, once
deployed, your application is exposed to a new category of possible attacks,
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 31f0b5a050c..4dcb416c110 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -148,6 +148,38 @@ Clicking on this button will create a merge request to apply the solution onto t
![Create merge request from vulnerability](img/create_issue_with_list_hover.png)
+## Security approvals in merge requests **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9928) in [GitLab Ultimate](https://about.gitlab.com/pricing) 12.2.
+
+Merge Request Approvals can be configured to require approval from a member
+of your security team when a vulnerability would be introduced by a merge request.
+
+This threshold is defined as `high`, `critical`, or `unknown`
+severity. When any vulnerabilities are present within a merge request, an
+approval will be required from the `Vulnerability-Check` approver group.
+
+### Enabling Security Approvals within a project
+
+To enable Security Approvals, a [project approval rule](../project/merge_requests/merge_request_approvals.md#multiple-approval-rules-premium)
+must be created with the case-sensitive name `Vulnerability-Check`. This approval
+group must be set with an "Approvals required" count greater than zero.
+
+Once this group has been added to your project, the approval rule will be enabled
+for all Merge Requests.
+
+Any code changes made will cause the count of approvals required to reset.
+
+An approval will be required when a security report:
+
+- Contains a new vulnerability of `high`, `critical`, or `unknown` severity.
+- Is not generated during pipeline execution.
+
+An approval will be optional when a security report:
+
+- Contains no new vulnerabilities.
+- Contains only new vulnerabilities of `low` or `medium` severity.
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index 7858c419e04..e6c27c33654 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -298,6 +298,79 @@ Web front-ends:
- `memory_limit_min` = 1024MiB
- `memory_limit_max` = 1280MiB
+## GitLab.com-specific rate limits
+
+NOTE: **Note:**
+See [Rate limits](../../security/rate_limits.md) for administrator
+documentation.
+
+IP blocks usually happen when GitLab.com receives unusual traffic from a single
+IP address that the system views as potentially malicious based on rate limit
+settings. After the unusual traffic ceases, the IP address will be automatically
+released depending on the type of block, as described below.
+
+If you receive a `403 Forbidden` error for all requests to GitLab.com, please
+check for any automated processes that may be triggering a block. For
+assistance, contact [GitLab Support](https://support.gitlab.com)
+with details, such as the affected IP address.
+
+### HAProxy API throttle
+
+GitLab.com responds with HTTP status code 429 to API requests over 10 requests
+per second per IP address.
+
+The following example headers are included for all API requests:
+
+```
+RateLimit-Limit: 600
+RateLimit-Observed: 6
+RateLimit-Remaining: 594
+RateLimit-Reset: 1563325137
+RateLimit-ResetTime: Wed, 17 Jul 2019 00:58:57 GMT
+```
+
+Source:
+
+- Search for `rate_limit_http_rate_per_minute` and `rate_limit_sessions_per_second` in [GitLab.com's current HAProxy settings](https://gitlab.com/gitlab-cookbooks/gitlab-haproxy/blob/master/attributes/default.rb).
+
+### Rack Attack initializer
+
+#### Protected paths throttle
+
+GitLab.com responds with HTTP status code 429 to POST requests at protected
+paths over 10 requests per **minute** per IP address.
+
+See the source below for which paths are protected. This includes user creation,
+user confirmation, user sign in, and password reset.
+
+This header is included in responses to blocked requests:
+
+```
+Retry-After: 60
+```
+
+Source:
+
+- Search for `rate_limit_requests_per_period`, `rate_limit_period`, and `rack_attack_protected_paths` in [GitLab.com's current Rails app settings](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-cookbooks/gitlab/attributes/default.rb).
+
+#### Git and container registry failed authentication ban
+
+GitLab.com responds with HTTP status code 403 for 1 hour, if 30 failed
+authentication requests were received in a 3-minute period from a single IP address.
+
+This applies only to Git requests and container registry (`/jwt/auth`) requests
+(combined).
+
+This limit is reset by requests that authenticate successfully. For example, 29
+failed authentication requests followed by 1 successful request, followed by 29
+more failed authentication requests would not trigger a ban.
+
+No response headers are provided.
+
+### Admin Area settings
+
+GitLab.com does not currently use these settings.
+
## GitLab.com at scale
In addition to the GitLab Enterprise Edition Omnibus install, GitLab.com uses
diff --git a/doc/user/project/img/key_value_labels.png b/doc/user/project/img/key_value_labels.png
deleted file mode 100644
index bec901f127f..00000000000
--- a/doc/user/project/img/key_value_labels.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_default.png b/doc/user/project/img/labels_default.png
deleted file mode 100644
index 221c5cf55a2..00000000000
--- a/doc/user/project/img/labels_default.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_default_v12_1.png b/doc/user/project/img/labels_default_v12_1.png
new file mode 100644
index 00000000000..4a0a6ba9ce0
--- /dev/null
+++ b/doc/user/project/img/labels_default_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_delete_v12_1.png b/doc/user/project/img/labels_delete_v12_1.png
new file mode 100644
index 00000000000..2e0ea934519
--- /dev/null
+++ b/doc/user/project/img/labels_delete_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_drag_priority_v12_1.gif b/doc/user/project/img/labels_drag_priority_v12_1.gif
new file mode 100644
index 00000000000..a568490da5f
--- /dev/null
+++ b/doc/user/project/img/labels_drag_priority_v12_1.gif
Binary files differ
diff --git a/doc/user/project/img/labels_epic_sidebar.png b/doc/user/project/img/labels_epic_sidebar.png
deleted file mode 100644
index f8162d89e9d..00000000000
--- a/doc/user/project/img/labels_epic_sidebar.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_epic_sidebar_v12_1.png b/doc/user/project/img/labels_epic_sidebar_v12_1.png
new file mode 100644
index 00000000000..7e05c6d1ce4
--- /dev/null
+++ b/doc/user/project/img/labels_epic_sidebar_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_generate_default.png b/doc/user/project/img/labels_generate_default.png
deleted file mode 100644
index 982a4df999c..00000000000
--- a/doc/user/project/img/labels_generate_default.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_generate_default_v12_1.png b/doc/user/project/img/labels_generate_default_v12_1.png
new file mode 100644
index 00000000000..48adc9a5699
--- /dev/null
+++ b/doc/user/project/img/labels_generate_default_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_group_issues.png b/doc/user/project/img/labels_group_issues.png
deleted file mode 100644
index cea1d304d31..00000000000
--- a/doc/user/project/img/labels_group_issues.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_group_issues_v12_1.png b/doc/user/project/img/labels_group_issues_v12_1.png
new file mode 100644
index 00000000000..bfe425f20ac
--- /dev/null
+++ b/doc/user/project/img/labels_group_issues_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_key_value_v12_1.png b/doc/user/project/img/labels_key_value_v12_1.png
new file mode 100644
index 00000000000..81d5c416c95
--- /dev/null
+++ b/doc/user/project/img/labels_key_value_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_list.png b/doc/user/project/img/labels_list.png
deleted file mode 100644
index 6940dde68bf..00000000000
--- a/doc/user/project/img/labels_list.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_list_v12_1.png b/doc/user/project/img/labels_list_v12_1.png
new file mode 100644
index 00000000000..c414ab42fbc
--- /dev/null
+++ b/doc/user/project/img/labels_list_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/new_label_from_sidebar.gif b/doc/user/project/img/labels_new_label_from_sidebar.gif
index 572b29a86e1..572b29a86e1 100644
--- a/doc/user/project/img/new_label_from_sidebar.gif
+++ b/doc/user/project/img/labels_new_label_from_sidebar.gif
Binary files differ
diff --git a/doc/user/project/img/labels_prioritized.png b/doc/user/project/img/labels_prioritized.png
deleted file mode 100644
index 7ce2d08b38c..00000000000
--- a/doc/user/project/img/labels_prioritized.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_prioritized_v12_1.png b/doc/user/project/img/labels_prioritized_v12_1.png
new file mode 100644
index 00000000000..8ea69949d8e
--- /dev/null
+++ b/doc/user/project/img/labels_prioritized_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_promotion.png b/doc/user/project/img/labels_promotion.png
deleted file mode 100644
index 762a3773692..00000000000
--- a/doc/user/project/img/labels_promotion.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_promotion_v12_1.png b/doc/user/project/img/labels_promotion_v12_1.png
new file mode 100644
index 00000000000..238d50981ae
--- /dev/null
+++ b/doc/user/project/img/labels_promotion_v12_1.png
Binary files differ
diff --git a/doc/user/project/img/labels_subscriptions.png b/doc/user/project/img/labels_subscriptions.png
deleted file mode 100644
index f3c4235d051..00000000000
--- a/doc/user/project/img/labels_subscriptions.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_subscriptions_v12_1.png b/doc/user/project/img/labels_subscriptions_v12_1.png
new file mode 100644
index 00000000000..57c437ac8a4
--- /dev/null
+++ b/doc/user/project/img/labels_subscriptions_v12_1.png
Binary files differ
diff --git a/doc/user/project/integrations/jira_server_configuration.md b/doc/user/project/integrations/jira_server_configuration.md
index 5116cbfe9ac..1efd0ff3944 100644
--- a/doc/user/project/integrations/jira_server_configuration.md
+++ b/doc/user/project/integrations/jira_server_configuration.md
@@ -3,8 +3,8 @@
We need to create a user in Jira which will have access to all projects that
need to integrate with GitLab.
-As an example, we'll create a user named `gitlab` and add it to the `Jira-developers`
-group.
+As an example, we'll create a user named `gitlab` and add it to a new group
+named `gitlab-developers`.
NOTE: **Note**
It is important that the Jira user created for the integration is given 'write'
diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md
index fdfeb4aa4cd..a00c1c980d2 100644
--- a/doc/user/project/labels.md
+++ b/doc/user/project/labels.md
@@ -2,43 +2,52 @@
## Overview
-Labels allow you to categorize issues or merge requests using descriptive titles like `bug`, `feature request`, or `docs`. Each label also has a customizable color. They allow you to quickly and dynamically filter and manage issues or merge requests you care about, and are visible throughout GitLab in most places where issues and merge requests are located.
+Labels allow you to categorize issues or merge requests using descriptive titles like
+`bug`, `feature request`, or `docs`. Each label also has a customizable color. They
+allow you to quickly and dynamically filter and manage issues or merge requests you
+care about, and are visible throughout GitLab in most places where issues and merge
+requests are located.
## Project labels and group labels
In GitLab, you can create project and group labels:
- **Project labels** can be assigned to issues or merge requests in that project only.
-- **Group labels** can be assigned to any issue or merge request of any project in that group or any subgroups of the group.
+- **Group labels** can be assigned to any issue or merge request in any project in
+ that group, or any subgroups of the group.
## Scoped labels **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9175) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
-Scoped labels allow teams to use the simple and familiar feature of labels to
+Scoped labels allow teams to use the simple and familiar label feature to
annotate their issues, merge requests, and epics to achieve custom fields and
custom workflow states by leveraging a special label title syntax.
-A scoped label is a kind of label defined only by a special double-colon syntax
+A scoped label is a kind of label defined by a special double-colon syntax
in the labelโ€™s title, using the format `key::value`. For example:
-![A sample scoped label](img/key_value_labels.png)
+![A sample scoped label](img/labels_key_value_v12_1.png)
An issue, epic, or merge request cannot have two scoped labels with the same key.
-For example, if an issue is already labeled `priority::3` and you apply the label `priority::2` to it,
-`priority::3` is automatically removed.
+For example, if an issue is already labeled `priority::3`, and then you apply the
+`priority::2` label to it, `priority::3` is automatically removed.
This functionality is demonstrated in a video titled [Use scoped labels in GitLab 11.10 for custom fields and custom workflows](https://www.youtube.com/watch?v=4BCBby6du3c).
### Labels with multiple colon pairs
-If labels have multiple instances of `::`, the longest path from left to right, until the last `::`, is considered the "key" or the "scope".
+If labels have multiple instances of `::`, the longest path from left to right, until
+the last `::`, is considered the "key" or the "scope".
-For example, `nested::key1::value1` and `nested::key1::value2` cannot both exist on the same issue. Adding the latter label will automatically remove the former due to the shared scope of `nested::key1`.
+For example, `nested::key1::value1` and `nested::key1::value2` cannot both exist on
+the same issue. Adding the latter label will automatically remove the former due to
+the shared scope of `nested::key1`.
-`nested::key1::value1` and `nested::key2::value1` can both exist on the same issue, as these are considered to use two different label scopes, `nested::key1` and `nested::key2`.
+`nested::key1::value1` and `nested::key2::value1` can both exist on the same issue,
+as these are considered to use two different label scopes, `nested::key1` and `nested::key2`.
-### Workflows with scoped labels **(PREMIUM)**
+### Workflows with scoped labels
Suppose you wanted a custom field in issues to track the platform operating system
that your features target, where each issue should only target one platform. You
@@ -58,101 +67,154 @@ be able to advance workflow states consistently in issues themselves.
## Creating labels
->**Note:**
+NOTE: **Note:**
A permission level of Reporter or higher is required to create labels.
### New project label
To create a **project label**, navigate to **Issues > Labels** in the project.
-This page only shows project labels in this project and group labels of this project's parent group.
+This page only shows the project labels in this project, and the group labels of the
+project's parent group.
-Click the **New label** button. Enter the title, an optional description, and the background color. Click **Create label** to create the label.
+Click the **New label** button. Enter the title, an optional description, and the
+background color. Click **Create label** to create the label.
-If a project has no labels, you can generate a default set of project labels from its empty label list page:
+If a project has no labels, you can generate a default set of project labels from
+its empty label list page:
-![Labels generate default](img/labels_generate_default.png)
+![Labels generate default](img/labels_generate_default_v12_1.png)
GitLab will add the following default labels to the project:
-![Labels default](img/labels_default.png)
+![Labels default](img/labels_default_v12_1.png)
### New group label
-To create a **group label**, follow similar steps from above to project labels. Navigate to **Issues > Labels** in the group and create it from there.
-This page only shows group labels in this group.
-Alternatively, you can create group labels also from Epic sidebar. Please note that the created label will belong to the immediate group to which epic belongs.
+To create a **group label**, navigate to **Issues > Labels** in the **group** and create
+it from there. This page only shows group labels in this group.
+
+Alternatively, you can create group labels from the Epic sidebar. Please note that the
+created label will belong to the immediate group to which the epic belongs. **(ULTIMATE)**
-![Create Labels from Epic](img/labels_epic_sidebar.png)
+![Create Labels from Epic](img/labels_epic_sidebar_v12_1.png)
Group labels appear in every label list page of the group's child projects.
-![Labels list](img/labels_list.png)
+![Labels list](img/labels_list_v12_1.png)
### New project label from sidebar
-From the sidebar of an issue or a merge request, you can create a new **project label** inline immediately, instead of navigating to the project label list page.
+From the sidebar of an issue or a merge request, you can create a new **project label**
+inline immediately, instead of navigating to the project label list page.
-![Labels inline](img/new_label_from_sidebar.gif)
+![Labels inline](img/labels_new_label_from_sidebar.gif)
## Editing labels
NOTE: **Note:**
A permission level of Reporter or higher is required to edit labels.
-You can update a label by navigating to **Issues > Labels** in the project or group and clicking the pencil icon.
+To update a label, navigate to **Issues > Labels** in the project or group
+and click the pencil icon. The title, description and color can be changed.
-You can delete a label by clicking the trash icon.
+To delete a label, click the three dots next to the `Subscribe` button, and select
+**Delete**.
+
+![Delete label](img/labels_delete_v12_1.png)
### Promoting project labels to group labels
-If you are expanding from a few projects to a larger number of projects within the same group, you may want to share the same label among multiple projects in the same group. If you previously created a project label and now want to make it available for other projects, you can promote it to a group label.
+If you are expanding from a few projects to a larger number of projects within the
+same group, you may want to share the same label among multiple projects in the same
+group. If you previously created a project label and now want to make it available
+for other projects, you can promote it to a group label.
-From the project label list page, you can promote a project label to a group label. This will merge all project labels across all projects in this group with the same name into a single group label. All issues and merge requests that previously were assigned one of these project labels will now be assigned the new group label. This action cannot be reversed and the changes are permanent.
+From the project label list page, you can promote a project label to a group label.
+This will merge all project labels with the same name into a single group label, across
+all projects in this group. All issues and merge requests that were previously
+assigned one of these project labels will now be assigned the new group label. This
+action cannot be reversed and the changes are permanent.
-![Labels promotion](img/labels_promotion.png)
+![Labels promotion](img/labels_promotion_v12_1.png)
## Assigning labels from the sidebar
-Every issue and merge request can be assigned any number of labels. The labels are visible on every issue and merge request page, in the sidebar. They are also visible in the issue board. From the sidebar, you can assign or unassign a label to the object (i.e. label or unlabel it). You can also perform this as a [quick action](quick_actions.md) in a comment.
+Every issue and merge request can be assigned any number of labels. The labels are
+visible on every issue and merge request page, in the sidebar. They are also visible on:
+
+- Every issue and merge request page in the sidebar.
+- The issue board.
+
+From the sidebar, you can assign or unassign a label to the object (i.e. label or
+unlabel it). You can also perform this as a [quick action](quick_actions.md),
+in a comment.
| View labels in sidebar | Assign labels from sidebar |
-|:---:|:---:|
+|:----------------------:|:--------------------------:|
| ![Labels sidebar](img/labels_sidebar.png) | ![Labels sidebar assign](img/labels_sidebar_assign.png) |
## Searching for project labels
-You can search for project labels by navigating from the left sidebar to your
-project's **Issues > Labels** and entering your query to the search bar on the
-top-right:
+To search for project labels, go to **Issues > Labels** in the left sidebar, and enter
+your search query in the **Filter** field.
![Labels project list search](img/labels_project_list_search.png)
-GitLab will consider the label title and description for the search.
+GitLab will check both the label titles and descriptions for the search.
+
+## Filtering by label
+
+The following can be filtered labels:
-## Filtering issues, merge requests and epics by label
+- Issue lists
+- Merge Request lists
+- Epic lists **(ULTIMATE)**
+- Issue Boards
### Filtering in list pages
-From the project issue list page and the project merge request list page, you can [filter](../search/index.md#issues-and-merge-requests) by both group (including subgroup ancestors) labels and project labels.
+- From the project issue list page and the project merge request list page, you can
+ [filter](../search/index.md#issues-and-merge-requests) by:
+ - Group labels (including subgroup ancestors)
+ - Project labels
-From the group issue list page and the group merge request list page, you can [filter](../search/index.md#issues-and-merge-requests) by both group labels (including subgroup ancestors and subgroup descendants) and project labels.
+- From the group issue list page and the group merge request list page, you can
+ [filter](../search/index.md#issues-and-merge-requests) by:
+ - Group labels (including subgroup ancestors and subgroup descendants)
+ - Project labels
-From the group epic list page, you can [filter](../search/index.md#issues-and-merge-requests) by both current group labels as well as descendant group labels.
+- You can [filter](../search/index.md#issues-and-merge-requests) the group epic list
+ page by: **(ULTIMATE)**
+ - Current group labels
+ - Descendant group labels
-![Labels group issues](img/labels_group_issues.png)
+![Labels group issues](img/labels_group_issues_v12_1.png)
### Filtering in issue boards
-- From [project boards](issue_board.md), you can filter by both group labels and project labels in the [search and filter bar](../search/index.md#issue-boards).
-- From [group issue boards](issue_board.md#group-issue-boards-premium), you can filter by only group labels in the [search and filter bar](../search/index.md#issue-boards). **(PREMIUM)**
-- From [project boards](issue_board.md), you can filter by both group labels and project labels in the [issue board configuration](issue_board.md#configurable-issue-boards-starter). **(STARTER)**
-- From [group issue boards](issue_board.md#group-issue-boards-premium), you can filter by only group labels in the [issue board configuration](issue_board.md#configurable-issue-boards-starter). **(STARTER)**
+- From [project boards](issue_board.md), you can use the [search and filter bar](../search/index.md#issue-boards)
+ to filter by:
+ - Group labels
+ - Project labels
+
+- From [group issue boards](issue_board.md#group-issue-boards-premium), you can use the
+ [search and filter bar](../search/index.md#issue-boards) to filter by group labels only. **(PREMIUM)**
+
+- From [project boards](issue_board.md), in the [issue board configuration](issue_board.md#configurable-issue-boards-starter),
+ you can filter by: **(STARTER)**
+ - Group labels
+ - Project labels
+
+- From [group issue boards](issue_board.md#group-issue-boards-premium), in the [issue board configuration](issue_board.md#configurable-issue-boards-starter),
+ you can filter by group labels only. **(STARTER)**
## Subscribing to labels
-From the project label list page and the group label list page, you can subscribe to [notifications](../../workflow/notifications.md) of a given label, to alert you that the label has been assigned to an issue or merge request.
+From the project label list page and the group label list page, you can subscribe
+to [notifications](../../workflow/notifications.md) of a given label, to alert you
+that the label has been assigned to an issue or merge request.
-![Labels subscriptions](img/labels_subscriptions.png)
+![Labels subscriptions](img/labels_subscriptions_v12_1.png)
## Label priority
@@ -161,26 +223,43 @@ From the project label list page and the group label list page, you can subscrib
> - Introduced in GitLab 8.9.
> - Priority sorting is based on the highest priority label only. [This discussion](https://gitlab.com/gitlab-org/gitlab-ce/issues/18554) considers changing this.
-Labels can have relative priorities, which are used in the "Label priority" and "Priority" sort orders of the issue and merge request list pages.
+Labels can have relative priorities, which are used in the "Label priority" and
+"Priority" sort orders of the issue and merge request list pages.
+
+From the project label list page, star a label to indicate that it has a priority.
+
+![Labels prioritized](img/labels_prioritized_v12_1.png)
+
+Drag starred labels up and down the list to change their priority. Higher in the list
+means higher priority. Prioritization happens at the project level, only on the project
+label list page, and not on the group label list page.
-From the project label list page, star a label to indicate that it has a priority. Drag starred labels up and down to change their priority. Higher means higher priority. Prioritization happens at the project level, only on the project label list page, and not on the group label list page. However, both project and group labels can be prioritized on the project label list page since both types are displayed on the project label list page.
+However, both project and group
+labels can be prioritized on the project label list page since both types are displayed
+on the project label list page.
-![Labels prioritized](img/labels_prioritized.png)
+![Drag to change label priority](img/labels_drag_priority_v12_1.gif)
-On the project and group issue and merge request list pages, you can sort by `Label priority` and `Priority`, which account for objects (issues and merge requests) that have prioritized labels assigned to them.
+On the merge request and issue pages, for both groups and projects, you can sort by `Label priority`
+and `Priority`, which account for objects (issues and merge requests) that have prioritized
+labels assigned to them.
If you sort by `Label priority`, GitLab considers this sort comparison order:
- Object with a higher priority prioritized label.
- Object without a prioritized label.
-Ties are broken arbitrarily. (Note that we _only_ consider the highest prioritized label in an object, and not any of the lower prioritized labels. [This discussion](https://gitlab.com/gitlab-org/gitlab-ce/issues/18554) considers changing this.)
+Ties are broken arbitrarily. Note that we _only_ consider the highest prioritized label
+in an object, and not any of the lower prioritized labels. [This discussion](https://gitlab.com/gitlab-org/gitlab-ce/issues/18554)
+considers changing this.
![Labels sort label priority](img/labels_sort_label_priority.png)
If you sort by `Priority`, GitLab considers this sort comparison order:
-- Object's assigned [milestone](milestones/index.md)'s due date is sooner, provided the object has a milestone and the milestone has a due date. If this isn't the case, consider the object having a due date in the infinite future.
+- Due date of the assigned [milestone](milestones/index.md) is sooner, provided
+ the object has a milestone and the milestone has a due date. If this isn't the case,
+ consider the object having a due date in the infinite future.
- Object with a higher priority prioritized label.
- Object without a prioritized label.
diff --git a/doc/user/project/merge_requests/merge_request_approvals.md b/doc/user/project/merge_requests/merge_request_approvals.md
index 220795d6f15..656459b3b03 100644
--- a/doc/user/project/merge_requests/merge_request_approvals.md
+++ b/doc/user/project/merge_requests/merge_request_approvals.md
@@ -331,6 +331,16 @@ the dropdown) `approver` and select the user.
![Filter MRs by an approver](img/filter_approver_merge_requests.png)
+## Security approvals in merge requests **(ULTIMATE)**
+
+> Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing) 12.2.
+
+Merge Request Approvals can be configured to require approval from a member
+of your security team when a vulnerability would be introduced by a merge request.
+
+For more information, see
+[Security approvals in merge requests](../../application_security/index.md#security-approvals-in-merge-requests-ultimate).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/project/packages/npm_registry.md b/doc/user/project/packages/npm_registry.md
index ca0aa9965ef..e01bac6b26f 100644
--- a/doc/user/project/packages/npm_registry.md
+++ b/doc/user/project/packages/npm_registry.md
@@ -81,6 +81,10 @@ domain name.
You should now be able to download and upload NPM packages to your project.
+NOTE: **Note:**
+If you encounter an error message with [Yarn](https://yarnpkg.com/en/), see the
+[troubleshooting section](#troubleshooting).
+
## Uploading packages
Before you will be able to upload a package, you need to specify the registry
@@ -116,3 +120,29 @@ a given scope, you will receive a `403 Forbidden!` error.
If you upload a package with a same name and version twice, GitLab will show
both packages in the UI, but the GitLab NPM Registry will expose the most recent
one as it supports only one package per version for `npm install`.
+
+## Troubleshooting
+
+### Error running yarn with NPM registry
+
+If you are using [yarn](https://yarnpkg.com/en/) with the NPM registry, you may get
+an error message like:
+
+```sh
+yarn install v1.15.2
+warning package.json: No license field
+info No lockfile found.
+warning XXX: No license field
+[1/4] ๐Ÿ” Resolving packages...
+[2/4] ๐Ÿšš Fetching packages...
+error An unexpected error occurred: "https://gitlab.com/api/v4/projects/XXX/packages/npm/XXX/XXX/-/XXX/XXX-X.X.X.tgz: Request failed \"404 Not Found\"".
+info If you think this is a bug, please open a bug report with the information provided in "/Users/XXX/gitlab-migration/module-util/yarn-error.log".
+info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command
+```
+
+In this case, try adding this to your `.npmrc` file (and replace `<your_oauth_token>`
+with your with your OAuth or personal access token):
+
+```text
+//gitlab.com/api/v4/projects/:_authToken=<your_oauth_token>
+```
diff --git a/doc/workflow/shortcuts.md b/doc/workflow/shortcuts.md
index fd67ea8ce87..d61d7eafd18 100644
--- a/doc/workflow/shortcuts.md
+++ b/doc/workflow/shortcuts.md
@@ -35,11 +35,11 @@ You can see GitLab's keyboard shortcuts by using <kbd>shift</kbd> + <kbd>?</kbd>
| Keyboard Shortcut | Description |
| ----------------- | ----------- |
-| <kbd>g</kbd> + <kbd>a</kbd> | Go to the activity feed |
-| <kbd>g</kbd> + <kbd>p</kbd> | Go to projects |
-| <kbd>g</kbd> + <kbd>i</kbd> | Go to issues |
-| <kbd>g</kbd> + <kbd>m</kbd> | Go to merge requests |
-| <kbd>g</kbd> + <kbd>t</kbd> | Go to todos |
+| <kbd>Shift</kbd> + <kbd>a</kbd> | Go to the activity feed |
+| <kbd>Shift</kbd> + <kbd>p</kbd> | Go to projects |
+| <kbd>Shift</kbd> + <kbd>i</kbd> | Go to issues |
+| <kbd>Shift</kbd> + <kbd>m</kbd> | Go to merge requests |
+| <kbd>Shift</kbd> + <kbd>t</kbd> | Go to todos |
## Project