Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-09-10 09:11:07 +00:00
parent ff2b80a554
commit 16e3c17d3f
55 changed files with 363 additions and 183 deletions

View file

@ -123,6 +123,7 @@
- "scripts/review_apps/base-config.yaml"
- "scripts/review_apps/review-apps.sh"
- "scripts/trigger-build"
- "{,ee/,jh/}{bin,config}/**/*.rb"
.ci-qa-patterns: &ci-qa-patterns
- ".gitlab-ci.yml"

View file

@ -56,7 +56,7 @@ export default {
const labelLink = h(
GlLink,
{
class: 'gl-display-flex gl-align-items-center label-item gl-text-black-normal',
class: 'gl-display-flex gl-align-items-center label-item gl-text-body',
on: {
click: () => {
listeners.clickLabel(label);

View file

@ -8,5 +8,6 @@ class Projects::WorkItemsController < Projects::ApplicationController
feature_category :not_owned
def index
render_404 unless Feature.enabled?(:work_items, project, default_enabled: :yaml)
end
end

View file

@ -1031,9 +1031,10 @@ module Ci
# Consider this object to have a structural integrity problems
def doom!
update_columns(
status: :failed,
failure_reason: :data_integrity_failure)
transaction do
update_columns(status: :failed, failure_reason: :data_integrity_failure)
all_queuing_entries.delete_all
end
end
def degradation_threshold

View file

@ -12,7 +12,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_user_create_mr
- i_code_review_user_create_mr_from_issue
distribution:
- ce
- ee

View file

@ -13,7 +13,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_user_create_mr
- i_code_review_user_create_mr_comment
distribution:
- ce
- ee

View file

@ -15,7 +15,7 @@ data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- p_ci_templates_auto_devops
- p_ci_templates_auto_devops_deploy
distribution:
- ce
- ee

View file

@ -521,7 +521,7 @@ For instructions about how to set up Patroni on the primary site, see the
#### Configuring Patroni cluster for a Geo secondary site
In a Geo secondary site, the main PostgreSQL database is a read-only replica of the primary sites PostgreSQL database.
In a Geo secondary site, the main PostgreSQL database is a read-only replica of the primary site's PostgreSQL database.
If you are currently using `repmgr` on your Geo primary site, see [these instructions](#migrating-from-repmgr-to-patroni)
for migrating from `repmgr` to Patroni.
@ -651,7 +651,7 @@ Refer to your preferred Load Balancer's documentation for further guidance.
##### Step 3. Configure a PgBouncer node on the secondary site
A production-ready and highly available configuration requires at least
three Consul nodes, a minimum of one PgBouncer node, but its recommended to have
three Consul nodes, a minimum of one PgBouncer node, but it's recommended to have
one per database node. An internal load balancer (TCP) is required when there is
more than one PgBouncer service nodes. The internal load balancer provides a single
endpoint for connecting to the PgBouncer cluster. For more information,

View file

@ -62,6 +62,12 @@ Housekeeping also [removes unreferenced LFS files](../raketasks/cleanup.md#remov
from your project on the same schedule as the `git gc` operation, freeing up storage space for your
project.
WARNING:
Running `git gc` or `git repack` commands manually in the
[repository folder](repository_storage_types.md#from-project-name-to-hashed-path)
is discouraged. If the created pack files get incorrect access rights (that is, owned by the wrong user)
browsing to the project page might result in `404` and `503` errors.
## How housekeeping handles pool repositories
Housekeeping for pool repositories is handled differently from standard repositories. It is
@ -76,7 +82,7 @@ This is the current call stack by which it is invoked:
1. `ObjectPoolService#fetch`
1. `Gitaly::FetchIntoObjectPoolRequest`
To manually invoke it from a Rails console if needed, you can call
To manually invoke it from a [Rails console](operations/rails_console.md) if needed, you can call
`project.pool_repository.object_pool.fetch`. This is a potentially long-running task, though Gitaly
times out in about 8 hours.

View file

@ -204,12 +204,20 @@ See [LDAP Rake Tasks - LDAP Check](ldap.md#check) for details.
The following are solutions to problems you might discover using the Rake tasks documented
above.
### Dangling commits
### Dangling objects
`gitlab:git:fsck` can find dangling commits. To fix them, try
[enabling housekeeping](../housekeeping.md).
The `gitlab:git:fsck` task can find dangling objects such as:
If the issue persists, try triggering `gc` via the
```plaintext
dangling blob a12...
dangling commit b34...
dangling tag c56...
dangling tree d78...
```
To delete them, try [running housekeeping](../housekeeping.md).
If the issue persists, try triggering garbage collection via the
[Rails Console](../operations/rails_console.md#starting-a-rails-console-session):
```ruby
@ -217,6 +225,13 @@ p = Project.find_by_path("project-name")
Repositories::HousekeepingService.new(p, :gc).execute
```
If the dangling objects are younger than the 2 weeks default grace period,
and you don't want to wait until they expire automatically, run:
```ruby
Repositories::HousekeepingService.new(p, :prune).execute
```
### Delete references to missing remote uploads
`gitlab-rake gitlab:uploads:check VERBOSE=1` detects remote objects that do not exist because they were

View file

@ -2390,7 +2390,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
use Google Clouds Kubernetes Engine (GKE) and associated machine types, but the memory
use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.

View file

@ -2402,7 +2402,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
use Google Clouds Kubernetes Engine (GKE) and associated machine types, but the memory
use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.

View file

@ -995,7 +995,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
use Google Clouds Kubernetes Engine (GKE) and associated machine types, but the memory
use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.

View file

@ -2124,7 +2124,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
use Google Clouds Kubernetes Engine (GKE) and associated machine types, but the memory
use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.

View file

@ -2413,7 +2413,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
use Google Clouds Kubernetes Engine (GKE) and associated machine types, but the memory
use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.

View file

@ -2094,7 +2094,7 @@ The following tables and diagram detail the hybrid environment using the same fo
as the normal environment above.
First are the components that run in Kubernetes. The recommendation at this time is to
use Google Clouds Kubernetes Engine (GKE) and associated machine types, but the memory
use Google Cloud's Kubernetes Engine (GKE) and associated machine types, but the memory
and CPU requirements should translate to most other providers. We hope to update this in the
future with further specific cloud provider details.

View file

@ -20,7 +20,7 @@ GET /projects/:id/jobs/:job_id/artifacts
|-------------|----------------|----------|--------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `job_id` | integer | yes | ID of a job. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request using the `PRIVATE-TOKEN` header:
@ -85,7 +85,7 @@ Parameters
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `ref_name` | string | yes | Branch or tag name in repository. HEAD or SHA references are not supported. |
| `job` | string | yes | The name of the job. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request using the `PRIVATE-TOKEN` header:
@ -146,7 +146,7 @@ Parameters
| `id` | integer/string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `job_id` | integer | yes | The unique job identifier. |
| `artifact_path` | string | yes | Path to a file inside the artifacts archive. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request:
@ -188,7 +188,7 @@ Parameters:
| `ref_name` | string | yes | Branch or tag name in repository. `HEAD` or `SHA` references are not supported. |
| `artifact_path` | string | yes | Path to a file inside the artifacts archive. |
| `job` | string | yes | The name of the job. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/triggers/index.md#when-a-pipeline-depends-on-the-artifacts-of-another-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
| `job_token` **(PREMIUM)** | string | no | To be used with [triggers](../ci/jobs/ci_job_token.md#download-an-artifact-from-a-different-pipeline) for multi-project pipelines. It should be invoked only inside `.gitlab-ci.yml`. Its value is always `$CI_JOB_TOKEN`. |
Example request:

View file

@ -4,7 +4,7 @@ group: Package
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Packages API
# Packages API **(FREE)**
This is the API documentation of [GitLab Packages](../administration/packages/index.md).

View file

@ -4,7 +4,7 @@ group: Release
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Pages API
# Pages API **(FREE)**
Endpoints for managing [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).

View file

@ -4,7 +4,7 @@ group: Release
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Pages domains API
# Pages domains API **(FREE)**
Endpoints for connecting custom domain(s) and TLS certificates in [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).

View file

@ -4,14 +4,14 @@ group: Compliance
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Personal access tokens API
# Personal access tokens API **(FREE)**
You can read more about [personal access tokens](../user/profile/personal_access_tokens.md#personal-access-tokens).
## List personal access tokens
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227264) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.3.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227264) in GitLab 13.3.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) from GitLab Ultimate to GitLab Free in 13.6.
Get a list of personal access tokens.
@ -70,8 +70,8 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
## Revoke a personal access token
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216004) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.3.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216004) in GitLab 13.3.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) from GitLab Ultimate to GitLab Free in 13.6.
Revoke a personal access token.

View file

@ -214,7 +214,7 @@ Sample response:
### Get a pipeline's test report summary
> Introduced in [GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65471)
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65471) in GitLab 14.2.
NOTE:
This API route is part of the [Unit test report](../ci/unit_test_reports.md) feature.

View file

@ -4,7 +4,7 @@ group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Plan limits API **(FREE)**
# Plan limits API **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54232) in GitLab 13.10.

View file

@ -7,7 +7,7 @@ type: reference, api
# Project Aliases API **(PREMIUM SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.1.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in GitLab 12.1.
All methods require administrator authorization.

View file

@ -294,7 +294,7 @@ Parameters:
| `platform_kubernetes_attributes[token]` | string | no | The token to authenticate against Kubernetes |
| `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. |
| `platform_kubernetes_attributes[namespace]` | string | no | The unique namespace related to the project |
| `environment_scope` | string | no | The associated environment to the cluster **(PREMIUM)** |
| `environment_scope` | string | no | The associated environment to the cluster |
NOTE:
`name`, `api_url`, `ca_cert` and `token` can only be updated if the cluster was added

View file

@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, api
---
# Project-level Variables API
# Project-level Variables API **(FREE)**
## List project variables

View file

@ -7,7 +7,7 @@ type: reference, api
# Project Vulnerabilities API **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in GitLab 12.6.
WARNING:
This API is in an alpha stage and considered unstable.

View file

@ -55,7 +55,7 @@ GET /projects
| `min_access_level` | integer | **{dotted-circle}** No | Limit by current user minimal [access level](members.md#valid-access-levels). |
| `order_by` | string | **{dotted-circle}** No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `last_activity_at`, or `similarity` fields. `repository_size`, `storage_size`, `packages_size` or `wiki_size` fields are only allowed for admins. `similarity` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332890) in GitLab 14.1) is only available when searching and is limited to projects that the current user is a member of. Default is `created_at`. |
| `owned` | boolean | **{dotted-circle}** No | Limit by projects explicitly owned by the current user. |
| `repository_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the repository checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2). |
| `repository_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the repository checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in GitLab 11.2). |
| `repository_storage` | string | **{dotted-circle}** No | Limit results to projects stored on `repository_storage`. _(admins only)_ |
| `search_namespaces` | boolean | **{dotted-circle}** No | Include ancestor namespaces when matching search criteria. Default is `false`. |
| `search` | string | **{dotted-circle}** No | Return list of projects matching the search criteria. |
@ -65,7 +65,7 @@ GET /projects
| `statistics` | boolean | **{dotted-circle}** No | Include project statistics. Only available to Reporter or higher level role members. |
| `topic` | string | **{dotted-circle}** No | Comma-separated topic names. Limit results to projects that match all of given topics. See `topics` attribute. |
| `visibility` | string | **{dotted-circle}** No | Limit by visibility `public`, `internal`, or `private`. |
| `wiki_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the wiki checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2). |
| `wiki_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the wiki checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in GitLab 11.2). |
| `with_custom_attributes` | boolean | **{dotted-circle}** No | Include [custom attributes](custom_attributes.md) in response. _(admins only)_ |
| `with_issues_enabled` | boolean | **{dotted-circle}** No | Limit by enabled issues feature. |
| `with_merge_requests_enabled` | boolean | **{dotted-circle}** No | Limit by enabled merge requests feature. |
@ -2428,7 +2428,7 @@ POST /projects/:id/housekeeping
## Push Rules **(PREMIUM)**
### Get project push rules **(PREMIUM)**
### Get project push rules
Get the [push rules](../push_rules/push_rules.md#enabling-push-rules) of a
project.
@ -2474,7 +2474,7 @@ parameters:
}
```
### Add project push rule **(PREMIUM)**
### Add project push rule
Adds a push rule to a specified project.
@ -2486,7 +2486,7 @@ POST /projects/:id/push_rule
|-----------------------------------------|----------------|------------------------|-------------|
| `author_email_regex` | string | **{dotted-circle}** No | All commit author emails must match this, for example `@my-company.com$`. |
| `branch_name_regex` | string | **{dotted-circle}** No | All branch names must match this, for example `(feature|hotfix)\/*`. |
| `commit_committer_check` **(PREMIUM)** | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
| `commit_committer_check` | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
| `commit_message_negative_regex` | string | **{dotted-circle}** No | No commit message is allowed to match this, for example `ssh\:\/\/`. |
| `commit_message_regex` | string | **{dotted-circle}** No | All commit messages must match this, for example `Fixed \d+\..*`. |
| `deny_delete_tag` | boolean | **{dotted-circle}** No | Deny deleting a tag. |
@ -2495,9 +2495,9 @@ POST /projects/:id/push_rule
| `max_file_size` | integer | **{dotted-circle}** No | Maximum file size (MB). |
| `member_check` | boolean | **{dotted-circle}** No | Restrict commits by author (email) to existing GitLab users. |
| `prevent_secrets` | boolean | **{dotted-circle}** No | GitLab rejects any files that are likely to contain secrets. |
| `reject_unsigned_commits` **(PREMIUM)** | boolean | **{dotted-circle}** No | Reject commit when it's not signed through GPG. |
| `reject_unsigned_commits` | boolean | **{dotted-circle}** No | Reject commit when it's not signed through GPG. |
### Edit project push rule **(PREMIUM)**
### Edit project push rule
Edits a push rule for a specified project.
@ -2509,7 +2509,7 @@ PUT /projects/:id/push_rule
|-----------------------------------------|----------------|------------------------|-------------|
| `author_email_regex` | string | **{dotted-circle}** No | All commit author emails must match this, for example `@my-company.com$`. |
| `branch_name_regex` | string | **{dotted-circle}** No | All branch names must match this, for example `(feature|hotfix)\/*`. |
| `commit_committer_check` **(PREMIUM)** | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
| `commit_committer_check` | boolean | **{dotted-circle}** No | Users can only push commits to this repository that were committed with one of their own verified emails. |
| `commit_message_negative_regex` | string | **{dotted-circle}** No | No commit message is allowed to match this, for example `ssh\:\/\/`. |
| `commit_message_regex` | string | **{dotted-circle}** No | All commit messages must match this, for example `Fixed \d+\..*`. |
| `deny_delete_tag` | boolean | **{dotted-circle}** No | Deny deleting a tag. |
@ -2518,7 +2518,7 @@ PUT /projects/:id/push_rule
| `max_file_size` | integer | **{dotted-circle}** No | Maximum file size (MB). |
| `member_check` | boolean | **{dotted-circle}** No | Restrict commits by author (email) to existing GitLab users. |
| `prevent_secrets` | boolean | **{dotted-circle}** No | GitLab rejects any files that are likely to contain secrets. |
| `reject_unsigned_commits` **(PREMIUM)** | boolean | **{dotted-circle}** No | Reject commits when they are not GPG signed. |
| `reject_unsigned_commits` | boolean | **{dotted-circle}** No | Reject commits when they are not GPG signed. |
### Delete project push rule

View file

@ -7,7 +7,7 @@ type: concepts, howto
# Protected environments API **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30595) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30595) in GitLab 12.8.
## Valid access levels

View file

@ -25,7 +25,7 @@ You can use a GitLab CI/CD job token to authenticate with specific API endpoints
- [Terraform plan](../../user/infrastructure/index.md).
The token has the same permissions to access the API as the user that triggers the
pipeline. Therefore, this user must be assigned to [a role that has the required privileges](../../user/permissions.md).
pipeline. Therefore, this user must be assigned to [a role that has the required privileges](../../user/permissions.md#gitlab-cicd-permissions).
The token is valid only while the pipeline job runs. After the job finishes, you can't
use the token anymore.
@ -123,3 +123,43 @@ To disable it:
```ruby
Feature.disable(:ci_scoped_job_token)
```
## Trigger a multi-project pipeline by using a CI job token
> `CI_JOB_TOKEN` for multi-project pipelines was [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) from GitLab Premium to GitLab Free in 12.4.
You can use the `CI_JOB_TOKEN` to trigger [multi-project pipelines](../pipelines/multi_project_pipelines.md)
from a CI/CD job. A pipeline triggered this way creates a dependent pipeline relation
that is visible on the [pipeline graph](../pipelines/multi_project_pipelines.md#multi-project-pipeline-visualization).
For example:
```yaml
trigger_pipeline:
stage: deploy
script:
- curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
rules:
- if: $CI_COMMIT_TAG
```
If you use the `CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md)
in a pipeline triggered this way, [the value is `pipeline` (not `triggered`)](../triggers/index.md#authentication-tokens).
## Download an artifact from a different pipeline **(PREMIUM)**
> `CI_JOB_TOKEN` for artifacts download with the API was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2346) in GitLab 9.5.
You can use the `CI_JOB_TOKEN` to access artifacts from a job created by a previous
pipeline. You must specify which job you want to retrieve the artifacts from:
```yaml
build_submodule:
stage: test
script:
- apt update && apt install -y unzip
- curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/main/download?job=test&job_token=$CI_JOB_TOKEN"
- unzip artifacts.zip
```
Read more about the [jobs artifacts API](../../api/job_artifacts.md#download-the-artifacts-archive).

View file

@ -225,7 +225,7 @@ check the value of the `$CI_PIPELINE_SOURCE` variable:
| `pipeline` | For [multi-project pipelines](../pipelines/multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../pipelines/multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](../yaml/index.md#trigger) keyword. |
| `push` | For pipelines triggered by a `git push` event, including for branches and tags. |
| `schedule` | For [scheduled pipelines](../pipelines/schedules.md). |
| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). |
| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#authentication-tokens). |
| `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
| `webide` | For pipelines created by using the [WebIDE](../../user/project/web_ide/index.md). |
@ -335,7 +335,7 @@ to control when to add jobs to pipelines.
In the following example, `job` runs only for:
- Git tags
- [Triggers](../triggers/index.md#trigger-token)
- [Triggers](../triggers/index.md#authentication-tokens)
- [Scheduled pipelines](../pipelines/schedules.md)
```yaml

View file

@ -273,7 +273,7 @@ upstream_bridge:
> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) to GitLab Free in 12.4.
When you use the [`CI_JOB_TOKEN` to trigger pipelines](../triggers/index.md#ci-job-token),
When you use the [`CI_JOB_TOKEN` to trigger pipelines](../jobs/ci_job_token.md),
GitLab recognizes the source of the job token. The pipelines become related,
so you can visualize their relationships on pipeline graphs.

View file

@ -14,8 +14,8 @@ tag) with an API call.
The following methods of authentication are supported:
- [Trigger token](#trigger-token)
- [CI job token](#ci-job-token)
- Trigger tokens: A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
- [CI job tokens](../jobs/ci_job_token.md).
If using the `$CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md)
to limit which jobs run in a pipeline, the value could be either `pipeline` or `trigger`,
@ -28,71 +28,6 @@ depending on which trigger method is used.
This also applies when using the `pipelines` or `triggers` keywords with the legacy [`only/except` basic syntax](../yaml/index.md#only--except).
### Trigger token
A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
WARNING:
Passing plain text tokens in public projects is a security issue. Potential
attackers can impersonate the user that exposed their trigger token publicly in
their `.gitlab-ci.yml` file. Use [CI/CD variables](../variables/index.md)
to protect trigger tokens.
### CI job token
You can use the `CI_JOB_TOKEN` [CI/CD variable](../variables/index.md#predefined-cicd-variables) (used to authenticate
with the [GitLab Container Registry](../../user/packages/container_registry/index.md)) in the following cases.
#### When used with multi-project pipelines
> - Use of `CI_JOB_TOKEN` for multi-project pipelines was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2017) in GitLab Premium 9.3.
> - Use of `CI_JOB_TOKEN` for multi-project pipelines was [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) from GitLab Premium to GitLab Free in 12.4.
This way of triggering can only be used when invoked inside `.gitlab-ci.yml`,
and it creates a dependent pipeline relation visible on the
[pipeline graph](../pipelines/multi_project_pipelines.md). For example:
```yaml
trigger_pipeline:
stage: deploy
script:
- curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
rules:
- if: $CI_COMMIT_TAG
```
Pipelines triggered that way also expose a special variable:
`CI_PIPELINE_SOURCE=pipeline`.
Read more about the [pipelines trigger API](../../api/pipeline_triggers.md).
#### When a pipeline depends on the artifacts of another pipeline **(PREMIUM)**
> The use of `CI_JOB_TOKEN` in the artifacts download API was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2346) in GitLab 9.5.
With the introduction of dependencies between different projects, one of
them may need to access artifacts created by a previous one. This process
must be granted for authorized accesses, and it can be done using the
`CI_JOB_TOKEN` variable that identifies a specific job. For example:
```yaml
build_submodule:
image: debian
stage: test
script:
- apt update && apt install -y unzip
- curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/main/download?job=test&job_token=$CI_JOB_TOKEN"
- unzip artifacts.zip
rules:
- if: $CI_COMMIT_TAG
```
This allows you to use that for multi-project pipelines and download artifacts
from any project to which you have access as this follows the same principles
with the [permission model](../../user/permissions.md#job-permissions).
Read more about the [jobs API](../../api/job_artifacts.md#download-the-artifacts-archive).
## Adding a new trigger
Go to your
@ -106,6 +41,12 @@ overview of the time the triggers were last used.
![Triggers page overview](img/triggers_page.png)
WARNING:
Passing plain text tokens in public projects is a security issue. Potential
attackers can impersonate the user that exposed their trigger token publicly in
their `.gitlab-ci.yml` file. Use [CI/CD variables](../variables/index.md)
to protect trigger tokens.
## Revoking a trigger
You can revoke a trigger any time by going at your project's

View file

@ -1367,7 +1367,7 @@ pipeline based on branch names or pipeline types.
| `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. |
| `schedules` | For [scheduled pipelines](../pipelines/schedules.md). |
| `tags` | When the Git reference for a pipeline is a tag. |
| `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). |
| `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#authentication-tokens). |
| `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
**Example of `only:refs` and `except:refs`**:

View file

@ -440,7 +440,7 @@ WARNING:
subsequent revisions for anything that would be spotted after that.
- For merge requests that have had [Squash and
merge](../user/project/merge_requests/squash_and_merge.md#squash-and-merge) set,
the squashed commits default commit message is taken from the merge request title.
the squashed commit's default commit message is taken from the merge request title.
You're encouraged to [select a commit with a more informative commit message](../user/project/merge_requests/squash_and_merge.md) before merging.
Thanks to **Pipeline for Merged Results**, authors no longer have to rebase their

View file

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

View file

@ -474,6 +474,7 @@ Follow these guidelines for punctuation:
| Use serial commas (Oxford commas) before the final **and** or **or** in a list of three or more items. (Tested in [`OxfordComma.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/OxfordComma.yml).) | You can create new issues, merge requests, and milestones. |
| Always add a space before and after dashes when using it in a sentence (for replacing a comma, for example). | You should try this - or not. |
| When a colon is part of a sentence, always use lowercase after the colon. | Linked issues: a way to create a relationship between issues. |
| Do not use typographer's quotes. Use straight quotes instead. (Tested in [`NonStandardQuotes.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/NonStandardQuotes.yml).) | "It's the questions we can't answer that teach us the most"---Patrick Rothfuss |
<!-- vale gitlab.Repetition = YES -->
@ -765,6 +766,7 @@ Valid for Markdown content only, not for front matter entries:
For other punctuation rules, refer to the
[Pajamas Design System Punctuation section](https://design.gitlab.com/content/punctuation/).
This is overridden by the [documentation-specific punctuation rules](#punctuation).
## Headings

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -19,7 +19,7 @@ The browser-based crawler works by loading the target application into a special
such as clicking on a link or filling in a form. For each action found, the crawler will execute it, take a new snapshot and determine what in the page changed from the previous snapshot.
Crawling continues by taking more snapshots and finding subsequent actions.
The benefit of crawling by following user actions in a browser is that the crawler can interact with the target application much like a real user would, identifying complex flows that traditional web crawlers dont understand. This results in better coverage of the website.
The benefit of crawling by following user actions in a browser is that the crawler can interact with the target application much like a real user would, identifying complex flows that traditional web crawlers don't understand. This results in better coverage of the website.
Using the browser-based crawler should provide greater coverage for most web applications, compared with the current DAST AJAX crawler. The new crawler replaces the AJAX crawler and is specifically designed to maximize crawl coverage in modern web applications. While both crawlers are currently used in conjunction with the existing DAST scanner, the combination of the browser-based crawler with the current DAST scanner is much more effective at finding and testing every page in an application.

View file

@ -49,7 +49,7 @@ can also be sorted by name or by the packager that installed them.
If a dependency has known vulnerabilities, view them by clicking the arrow next to the
dependency's name or the badge that indicates how many known vulnerabilities exist. For each
vulnerability, its severity and description appears below it. To view more details of a vulnerability,
select the vulnerabilitys description. The [vulnerability's details](../vulnerabilities) page is opened.
select the vulnerability's description. The [vulnerability's details](../vulnerabilities) page is opened.
### Dependency paths
@ -78,8 +78,8 @@ You can download your project's full list of dependencies and their details in
### In the UI
You can download your projects list of dependencies and their details in JSON format by selecting the **Export** button. Note that the dependency list only shows the results of the last successful pipeline to run on the default branch.
You can download your project's list of dependencies and their details in JSON format by selecting the **Export** button. Note that the dependency list only shows the results of the last successful pipeline to run on the default branch.
### Using the API
You can download your projects list of dependencies [using the API](../../../api/dependencies.md#list-project-dependencies). Note this only provides the dependencies identified by the gemnasium family of analyzers and [not any other of the GitLab dependency analyzers](../dependency_scanning/analyzers.md).
You can download your project's list of dependencies [using the API](../../../api/dependencies.md#list-project-dependencies). Note this only provides the dependencies identified by the gemnasium family of analyzers and [not any other of the GitLab dependency analyzers](../dependency_scanning/analyzers.md).

View file

@ -271,7 +271,7 @@ under your project's settings:
## DAST On-Demand Scans
If you dont want scans running in your normal DevOps process you can use on-demand scans instead. For more details, see [on-demand scans](dast/index.md#on-demand-scans). This feature is only available for DAST. If you run an on-demand scan against the default branch, it is reported as a "successful pipeline" and these results are included in the security dashboard and vulnerability report.
If you don't want scans running in your normal DevOps process you can use on-demand scans instead. For more details, see [on-demand scans](dast/index.md#on-demand-scans). This feature is only available for DAST. If you run an on-demand scan against the default branch, it is reported as a "successful pipeline" and these results are included in the security dashboard and vulnerability report.
## Security report validation

View file

@ -154,7 +154,7 @@ To use CI/CD to authenticate, you can use:
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
```
- A [CI job token](../../../ci/triggers/index.md#ci-job-token).
- A [CI job token](../../../ci/jobs/ci_job_token.md).
```shell
docker login -u $CI_JOB_USER -p $CI_JOB_TOKEN $CI_REGISTRY

View file

@ -524,7 +524,7 @@ To avoid the time sync issue, enable time synchronization in the device that gen
1. Go to Settings.
1. Select General.
1. Select Date & Time.
1. Enable Set Automatically. If its already enabled, disable it, wait a few seconds, and re-enable.
1. Enable Set Automatically. If it's already enabled, disable it, wait a few seconds, and re-enable.
<!-- ## Troubleshooting

View file

@ -126,6 +126,10 @@ module API
expose :keep_latest_artifacts_available?, as: :keep_latest_artifact
# rubocop: disable CodeReuse/ActiveRecord
def self.preload_resource(project)
ActiveRecord::Associations::Preloader.new.preload(project, project_group_links: { group: :route })
end
def self.preload_relation(projects_relation, options = {})
# Preloading topics, should be done with using only `:topics`,
# as `:topics` are defined as: `has_many :topics, through: :taggings`

View file

@ -152,6 +152,12 @@ module API
ProjectsFinder.new(current_user: current_user, params: project_params).execute
end
def present_project(project, options = {})
options[:with].preload_resource(project) if options[:with].respond_to?(:preload_resource)
present project, options
end
def present_projects(projects, options = {})
verify_statistics_order_by_projects!
@ -264,9 +270,9 @@ module API
project = ::Projects::CreateService.new(current_user, attrs).execute
if project.saved?
present project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, project),
current_user: current_user
present_project project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, project),
current_user: current_user
else
if project.errors[:limit_reached].present?
error!(project.errors[:limit_reached], 403)
@ -301,9 +307,9 @@ module API
project = ::Projects::CreateService.new(user, attrs).execute
if project.saved?
present project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, project),
current_user: current_user
present_project project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, project),
current_user: current_user
else
render_validation_error!(project)
end
@ -336,7 +342,7 @@ module API
project, options = with_custom_attributes(user_project, options)
present project, options
present_project project, options
end
desc 'Fork new project for the current user or provided namespace.' do
@ -376,9 +382,11 @@ module API
if forked_project.errors.any?
conflict!(forked_project.errors.messages)
else
present forked_project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, forked_project),
current_user: current_user
present_project forked_project, {
with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, forked_project),
current_user: current_user
}
end
end
@ -427,9 +435,9 @@ module API
result = ::Projects::UpdateService.new(user_project, current_user, attrs).execute
if result[:status] == :success
present user_project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, user_project),
current_user: current_user
present_project user_project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, user_project),
current_user: current_user
else
render_validation_error!(user_project)
end
@ -443,7 +451,7 @@ module API
::Projects::UpdateService.new(user_project, current_user, archived: true).execute
present user_project, with: Entities::Project, current_user: current_user
present_project user_project, with: Entities::Project, current_user: current_user
end
desc 'Unarchive a project' do
@ -454,7 +462,7 @@ module API
::Projects::UpdateService.new(user_project, current_user, archived: false).execute
present user_project, with: Entities::Project, current_user: current_user
present_project user_project, with: Entities::Project, current_user: current_user
end
desc 'Star a project' do
@ -467,7 +475,7 @@ module API
current_user.toggle_star(user_project)
user_project.reset
present user_project, with: Entities::Project, current_user: current_user
present_project user_project, with: Entities::Project, current_user: current_user
end
end
@ -479,7 +487,7 @@ module API
current_user.toggle_star(user_project)
user_project.reset
present user_project, with: Entities::Project, current_user: current_user
present_project user_project, with: Entities::Project, current_user: current_user
else
not_modified!
end
@ -528,7 +536,7 @@ module API
result = ::Projects::ForkService.new(fork_from_project, current_user).execute(user_project)
if result
present user_project.reset, with: Entities::Project, current_user: current_user
present_project user_project.reset, with: Entities::Project, current_user: current_user
else
render_api_error!("Project already forked", 409) if user_project.forked?
end
@ -698,7 +706,7 @@ module API
result = ::Projects::TransferService.new(user_project, current_user).execute(namespace)
if result
present user_project, with: Entities::Project, current_user: current_user
present_project user_project, with: Entities::Project, current_user: current_user
else
render_api_error!("Failed to transfer project #{user_project.errors.messages}", 400)
end

View file

@ -10,7 +10,7 @@ module Gitlab
def initialize(variables = [], errors = nil)
@variables = []
@variables_by_key = {}
@variables_by_key = Hash.new { |h, k| h[k] = [] }
@errors = errors
variables.each { |variable| self.append(variable) }
@ -19,7 +19,7 @@ module Gitlab
def append(resource)
item = Collection::Item.fabricate(resource)
@variables.append(item)
@variables_by_key[item[:key]] = item
@variables_by_key[item[:key]] << item
self
end
@ -46,7 +46,12 @@ module Gitlab
end
def [](key)
@variables_by_key[key]
all(key)&.last
end
def all(key)
vars = @variables_by_key[key]
vars unless vars.empty?
end
def size
@ -72,7 +77,7 @@ module Gitlab
match = Regexp.last_match
if match[:key]
# we matched variable
if variable = @variables_by_key[match[:key]]
if variable = self[match[:key]]
variable.value
elsif keep_undefined
match[0]

View file

@ -42,7 +42,7 @@ module Gitlab
depends_on = var_item.depends_on
return unless depends_on
depends_on.filter_map { |var_ref_name| @collection[var_ref_name] }.each(&block)
depends_on.filter_map { |var_ref_name| @collection.all(var_ref_name) }.flatten.each(&block)
end
end
end

View file

@ -5,19 +5,20 @@ module Gitlab
module Loaders
# Suitable for use to find resources that expose `where_full_path_in`,
# such as Project, Group, Namespace
# full path is always converted to lowercase for case-insensitive results
class FullPathModelLoader
attr_reader :model_class, :full_path
def initialize(model_class, full_path)
@model_class = model_class
@full_path = full_path
@full_path = full_path.downcase
end
def find
BatchLoader::GraphQL.for(full_path).batch(key: model_class) do |full_paths, loader, args|
# `with_route` avoids an N+1 calculating full_path
args[:key].where_full_path_in(full_paths).with_route.each do |model_instance|
loader.call(model_instance.full_path, model_instance)
loader.call(model_instance.full_path.downcase, model_instance)
end
end
end

View file

@ -22888,8 +22888,10 @@ msgstr ""
msgid "No webhooks found, add one in the form above."
msgstr ""
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription."
msgstr ""
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} day to renew your subscription."
msgid_plural "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} days to renew your subscription."
msgstr[0] ""
msgstr[1] ""
msgid "No. of commits"
msgstr ""
@ -33230,7 +33232,7 @@ msgstr ""
msgid "Thanks for your purchase!"
msgstr ""
msgid "That is ok, I do not want to renew"
msgid "That's OK, I don't want to renew"
msgstr ""
msgid "That's it, well done!"
@ -38771,10 +38773,10 @@ msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}."
msgid "Your %{strong}%{plan_name}%{strong_close} subscription expires on %{strong}%{expires_on}%{strong_close}. After that date, you cannot create issues or merge requests, or use many other features."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not be able to create issues or merge requests as well as many other features."
msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}."
msgstr ""
msgid "Your CI/CD configuration syntax is invalid. View Lint tab for more details."
@ -39053,8 +39055,10 @@ msgstr ""
msgid "Your subscription has been downgraded."
msgstr ""
msgid "Your subscription will expire in %{remaining_days}."
msgstr ""
msgid "Your subscription will expire in %{remaining_days} day."
msgid_plural "Your subscription will expire in %{remaining_days} days."
msgstr[0] ""
msgstr[1] ""
msgid "Your username is %{username}."
msgstr ""

View file

@ -20,10 +20,15 @@ RSpec.describe Resolvers::GroupResolver do
end
it 'resolves an unknown full_path to nil' do
result = batch_sync { resolve_group('unknown/project') }
result = batch_sync { resolve_group('unknown/group') }
expect(result).to be_nil
end
it 'treats group full path as case insensitive' do
result = batch_sync { resolve_group(group1.full_path.upcase) }
expect(result).to eq group1
end
end
def resolve_group(full_path)

View file

@ -25,6 +25,11 @@ RSpec.describe Resolvers::ProjectResolver do
expect(result).to be_nil
end
it 'treats project full path as case insensitive' do
result = batch_sync { resolve_project(project1.full_path.upcase) }
expect(result).to eq project1
end
end
it 'does not increase complexity depending on number of load limits' do

View file

@ -5,20 +5,10 @@ require 'rspec-parameterized'
RSpec.describe Gitlab::Ci::Variables::Collection::Sort do
describe '#initialize with non-Collection value' do
context 'when FF :variable_inside_variable is disabled' do
subject { Gitlab::Ci::Variables::Collection::Sort.new([]) }
subject { Gitlab::Ci::Variables::Collection::Sort.new([]) }
it 'raises ArgumentError' do
expect { subject }.to raise_error(ArgumentError, /Collection object was expected/)
end
end
context 'when FF :variable_inside_variable is enabled' do
subject { Gitlab::Ci::Variables::Collection::Sort.new([]) }
it 'raises ArgumentError' do
expect { subject }.to raise_error(ArgumentError, /Collection object was expected/)
end
it 'raises ArgumentError' do
expect { subject }.to raise_error(ArgumentError, /Collection object was expected/)
end
end
@ -182,5 +172,33 @@ RSpec.describe Gitlab::Ci::Variables::Collection::Sort do
expect { subject }.to raise_error(TSort::Cyclic)
end
end
context 'with overridden variables' do
let(:variables) do
[
{ key: 'PROJECT_VAR', value: '$SUBGROUP_VAR' },
{ key: 'SUBGROUP_VAR', value: '$TOP_LEVEL_GROUP_NAME' },
{ key: 'SUBGROUP_VAR', value: '$SUB_GROUP_NAME' },
{ key: 'TOP_LEVEL_GROUP_NAME', value: 'top-level-group' },
{ key: 'SUB_GROUP_NAME', value: 'vars-in-vars-subgroup' }
]
end
let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) }
subject do
Gitlab::Ci::Variables::Collection::Sort.new(collection).tsort.map { |v| { v[:key] => v.value } }
end
it 'preserves relative order of overridden variables' do
is_expected.to eq([
{ 'TOP_LEVEL_GROUP_NAME' => 'top-level-group' },
{ 'SUBGROUP_VAR' => '$TOP_LEVEL_GROUP_NAME' },
{ 'SUB_GROUP_NAME' => 'vars-in-vars-subgroup' },
{ 'SUBGROUP_VAR' => '$SUB_GROUP_NAME' },
{ 'PROJECT_VAR' => '$SUBGROUP_VAR' }
])
end
end
end
end

View file

@ -123,17 +123,102 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
end
describe '#[]' do
variable = { key: 'VAR', value: 'value', public: true, masked: false }
subject { Gitlab::Ci::Variables::Collection.new(variables)[var_name] }
collection = described_class.new([variable])
shared_examples 'an array access operator' do
context 'for a non-existent variable name' do
let(:var_name) { 'UNKNOWN_VAR' }
it 'returns nil for a non-existent variable name' do
expect(collection['UNKNOWN_VAR']).to be_nil
it 'returns nil' do
is_expected.to be_nil
end
end
context 'for an existent variable name' do
let(:var_name) { 'VAR' }
it 'returns the last Item' do
is_expected.to be_an_instance_of(Gitlab::Ci::Variables::Collection::Item)
expect(subject.to_runner_variable).to eq(variables.last)
end
end
end
it 'returns Item for an existent variable name' do
expect(collection['VAR']).to be_an_instance_of(Gitlab::Ci::Variables::Collection::Item)
expect(collection['VAR'].to_runner_variable).to eq(variable)
context 'with variable key with single entry' do
let(:variables) do
[
{ key: 'VAR', value: 'value', public: true, masked: false }
]
end
it_behaves_like 'an array access operator'
end
context 'with variable key with multiple entries' do
let(:variables) do
[
{ key: 'VAR', value: 'value', public: true, masked: false },
{ key: 'VAR', value: 'override value', public: true, masked: false }
]
end
it_behaves_like 'an array access operator'
end
end
describe '#all' do
subject { described_class.new(variables).all(var_name) }
shared_examples 'a method returning all known variables or nil' do
context 'for a non-existent variable name' do
let(:var_name) { 'UNKNOWN_VAR' }
it 'returns nil' do
is_expected.to be_nil
end
end
context 'for an existing variable name' do
let(:var_name) { 'VAR' }
it 'returns all expected Items' do
is_expected.to eq(expected_variables.map { |v| Gitlab::Ci::Variables::Collection::Item.fabricate(v) })
end
end
end
context 'with variable key with single entry' do
let(:variables) do
[
{ key: 'VAR', value: 'value', public: true, masked: false }
]
end
it_behaves_like 'a method returning all known variables or nil' do
let(:expected_variables) do
[
{ key: 'VAR', value: 'value', public: true, masked: false }
]
end
end
end
context 'with variable key with multiple entries' do
let(:variables) do
[
{ key: 'VAR', value: 'value', public: true, masked: false },
{ key: 'VAR', value: 'override value', public: true, masked: false }
]
end
it_behaves_like 'a method returning all known variables or nil' do
let(:expected_variables) do
[
{ key: 'VAR', value: 'value', public: true, masked: false },
{ key: 'VAR', value: 'override value', public: true, masked: false }
]
end
end
end
end

View file

@ -5269,4 +5269,23 @@ RSpec.describe Ci::Build do
build.ensure_trace_metadata!
end
end
describe '#doom!' do
subject { build.doom! }
let_it_be(:build) { create(:ci_build, :queued) }
it 'updates status and failure_reason', :aggregate_failures do
subject
expect(build.status).to eq("failed")
expect(build.failure_reason).to eq("data_integrity_failure")
end
it 'drops associated pending build' do
subject
expect(build.reload.queuing_entry).not_to be_present
end
end
end

View file

@ -2616,6 +2616,23 @@ RSpec.describe API::Projects do
expect(json_response).to have_key 'service_desk_enabled'
expect(json_response).to have_key 'service_desk_address'
end
context 'when project is shared to multiple groups' do
it 'avoids N+1 queries' do
create(:project_group_link, project: project)
get api("/projects/#{project.id}", user)
control = ActiveRecord::QueryRecorder.new do
get api("/projects/#{project.id}", user)
end
create(:project_group_link, project: project)
expect do
get api("/projects/#{project.id}", user)
end.not_to exceed_query_limit(control)
end
end
end
describe 'GET /projects/:id/users' do