Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
ff2b80a554
commit
16e3c17d3f
55 changed files with 363 additions and 183 deletions
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 site’s 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 it’s 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,
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 Cloud’s 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.
|
||||
|
||||
|
|
|
@ -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 Cloud’s 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.
|
||||
|
||||
|
|
|
@ -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 Cloud’s 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.
|
||||
|
||||
|
|
|
@ -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 Cloud’s 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.
|
||||
|
||||
|
|
|
@ -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 Cloud’s 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.
|
||||
|
||||
|
|
|
@ -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 Cloud’s 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.
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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/).
|
||||
|
||||
|
|
|
@ -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/).
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`**:
|
||||
|
|
|
@ -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 commit’s 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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 |
|
@ -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 don’t 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.
|
||||
|
||||
|
|
|
@ -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 vulnerability’s 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 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.
|
||||
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 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).
|
||||
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).
|
||||
|
|
|
@ -271,7 +271,7 @@ under your project's settings:
|
|||
|
||||
## DAST On-Demand Scans
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 it’s 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
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue