Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-20 21:10:29 +00:00
parent 29f6c0bff8
commit 68964241ec
19 changed files with 279 additions and 209 deletions

View file

@ -854,7 +854,6 @@ Layout/ArgumentAlignment:
- 'spec/rubocop/cop/rspec/be_success_matcher_spec.rb'
- 'spec/serializers/feature_flag_entity_spec.rb'
- 'spec/serializers/feature_flag_serializer_spec.rb'
- 'spec/serializers/pipeline_serializer_spec.rb'
- 'spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb'
- 'spec/services/award_emojis/destroy_service_spec.rb'
- 'spec/services/bulk_update_integration_service_spec.rb'

View file

@ -171,7 +171,6 @@ RSpec/InstanceVariable:
- spec/requests/openid_connect_spec.rb
- spec/requests/projects/issues/discussions_spec.rb
- spec/rubocop/cop/migration/update_column_in_batches_spec.rb
- spec/serializers/pipeline_serializer_spec.rb
- spec/services/ci/create_pipeline_service/logger_spec.rb
- spec/services/ci/process_sync_events_service_spec.rb
- spec/services/labels/update_service_spec.rb

View file

@ -414,7 +414,6 @@ RSpec/PredicateMatcher:
- 'spec/requests/api/users_spec.rb'
- 'spec/requests/git_http_spec.rb'
- 'spec/requests/lfs_http_spec.rb'
- 'spec/serializers/pipeline_serializer_spec.rb'
- 'spec/services/branches/create_service_spec.rb'
- 'spec/services/ci/create_pipeline_service/needs_spec.rb'
- 'spec/services/ci/create_pipeline_service/rate_limit_spec.rb'

View file

@ -0,0 +1,8 @@
---
name: ci_remove_userless_ci
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92942
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/368427
milestone: '15.5'
type: development
group: group::pipeline execution
default_enabled: false

View file

@ -0,0 +1,8 @@
---
name: container_registry_tags_list_default_page_size
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98215
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/374073
milestone: '15.5'
type: development
group: group::package
default_enabled: false

View file

@ -0,0 +1,26 @@
# frozen_string_literal: true
class DropUnusedFieldsFromMergeRequestReviewers < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
def up
with_lock_retries do
if column_exists?(:merge_request_reviewers, :updated_state_by_user_id)
remove_column :merge_request_reviewers, :updated_state_by_user_id
end
end
end
def down
with_lock_retries do
unless column_exists?(:merge_request_reviewers, :updated_state_by_user_id)
add_column :merge_request_reviewers, :updated_state_by_user_id, :bigint
end
end
add_concurrent_index :merge_request_reviewers, :updated_state_by_user_id,
name: 'index_on_merge_request_reviewers_updated_state_by_user_id'
add_concurrent_foreign_key :merge_request_reviewers, :users, column: :updated_state_by_user_id, on_delete: :nullify
end
end

View file

@ -0,0 +1 @@
a4115d5542d236a030db180363cf2c816ff68cd2c2a54e74a6b3ba916a40816e

View file

@ -17514,8 +17514,7 @@ CREATE TABLE merge_request_reviewers (
user_id bigint NOT NULL,
merge_request_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
state smallint DEFAULT 0 NOT NULL,
updated_state_by_user_id bigint
state smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE merge_request_reviewers_id_seq
@ -29545,8 +29544,6 @@ CREATE INDEX index_on_merge_request_assignees_updated_state_by_user_id ON merge_
CREATE INDEX index_on_merge_request_assignees_user_id_and_state ON merge_request_assignees USING btree (user_id, state) WHERE (state = 2);
CREATE INDEX index_on_merge_request_reviewers_updated_state_by_user_id ON merge_request_reviewers USING btree (updated_state_by_user_id);
CREATE INDEX index_on_merge_request_reviewers_user_id_and_state ON merge_request_reviewers USING btree (user_id, state) WHERE (state = 2);
CREATE INDEX index_on_merge_requests_for_latest_diffs ON merge_requests USING btree (target_project_id) INCLUDE (id, latest_merge_request_diff_id);
@ -32512,9 +32509,6 @@ ALTER TABLE ONLY epics
ALTER TABLE ONLY ci_pipelines
ADD CONSTRAINT fk_3d34ab2e06 FOREIGN KEY (pipeline_schedule_id) REFERENCES ci_pipeline_schedules(id) ON DELETE SET NULL;
ALTER TABLE ONLY merge_request_reviewers
ADD CONSTRAINT fk_3d674b9f23 FOREIGN KEY (updated_state_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY protected_environment_approval_rules
ADD CONSTRAINT fk_405568b491 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;

View file

@ -7,8 +7,6 @@ type: reference, api
# Project Aliases API **(PREMIUM SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in GitLab 12.1.
All methods require administrator authorization.
## List all project aliases
@ -50,7 +48,7 @@ GET /project_aliases/:name
| Attribute | Type | Required | Description |
|-----------|--------|----------|-----------------------|
| `name` | string | yes | The name of the alias |
| `name` | string | **{check-circle}** Yes | The name of the alias. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/project_aliases/gitlab"
@ -77,8 +75,8 @@ POST /project_aliases
| Attribute | Type | Required | Description |
|--------------|----------------|----------|----------------------------------------|
| `project_id` | integer/string | yes | The ID or path of the project. |
| `name` | string | yes | The name of the alias. Must be unique. |
| `name` | string | **{check-circle}** Yes | The name of the alias. Must be unique. |
| `project_id` | integer or string | **{check-circle}** Yes | The ID or path of the project. |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
@ -113,7 +111,7 @@ DELETE /project_aliases/:name
| Attribute | Type | Required | Description |
|-----------|--------|----------|-----------------------|
| `name` | string | yes | The name of the alias |
| `name` | string | **{check-circle}** Yes | The name of the alias. |
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/project_aliases/gitlab"

View file

@ -676,125 +676,66 @@ 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).
### Anchor links
Headings generate anchor links when rendered. `## This is an example` generates
the anchor `#this-is-an-example`.
NOTE:
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39717) in
GitLab 13.4, [product badges](#product-tier-badges) used in headings aren't
included in the generated anchor links. For example, when you link to
`## This is an example **(FREE)**`, use the anchor `#this-is-an-example`.
Keep in mind that the GitLab user interface links to many documentation pages
and anchor links to take the user to the right spot. When you change
a heading, search `doc/*`, `app/views/*`, and `ee/app/views/*` for the old
anchor. If you do not fix these links, the [`ui-docs-lint` job](../testing.md#ui-link-tests)
in your merge request fails.
Important:
- Avoid crosslinking documentation to headings unless you need to link to a
specific section of the document. This avoids breaking anchors in the
future in case the heading is changed.
- If possible, avoid changing headings, because they're not only linked internally.
There are various links to GitLab documentation on the internet, such as
tutorials, presentations, StackOverflow posts, and other sources.
- Do not link to `h1` headings.
Note that with Kramdown, it's possible to add a custom ID to an HTML element
with Markdown markup, but they don't work in `/help`. Because of this, don't use
this option.
## Links
Links are important in GitLab documentation. Use links instead of
summarizing to help preserve a [single source of truth](#documentation-is-the-single-source-of-truth-ssot)
in GitLab documentation.
Links help the docs adhere to the
[single source of truth](#documentation-is-the-single-source-of-truth-ssot) principle.
We include guidance for links in these categories:
### Links within the same repository
- How to set up [anchor links](#anchor-links) for headings.
- How to set up [criteria](#basic-link-criteria) for configuring a link.
- What to set up when [linking to a `help`](../../documentation/index.md#linking-to-help)
page.
- How to set up [links to internal documentation](#links-to-internal-documentation)
for cross-references.
- How to set up [links to external documentation](#links-to-external-documentation)
for authoritative sources.
- When to use [links requiring permissions](#links-requiring-permissions).
- How to set up a [link to a video](#link-to-video).
- How to [link to specific lines of code](#link-to-specific-lines-of-code)
To link to another page in the same repository,
use a relative file path. For example, `../user/gitlab_com/index.md`.
### Basic link criteria
Use inline link Markdown markup `[Text](https://example.com)`,
rather than reference-style links, like `[Text][identifier]`.
- Use inline link Markdown markup `[Text](https://example.com)`.
It's easier to read, review, and maintain. Do not use `[Text][identifier]` reference-style links.
- Use meaningful anchor text.
For example, instead of writing something like `Read more about merge requests [here](LINK)`,
write `Read more about [merge requests](LINK)`.
- Put the entire link on a single line. Some of our [linters](../testing.md) do not
validate links when split over multiple lines, and incorrect or broken links could
slip through.
Put the entire link on a single line so that [linters](../testing.md) can find it.
### Links to internal documentation
### Links in separate repositories
NOTE:
**Internal** refers to documentation in the same project. When linking to
documentation in separate projects (for example, linking to Omnibus documentation
from GitLab documentation), you must use absolute URLs.
To link to a page in a different repository, use an absolute URL.
For example, to link from a page in the GitLab repo to the Charts repo,
use a URL like `https://docs.gitlab.com/charts/`.
Do not use absolute URLs like `https://docs.gitlab.com/ee/index.html` to
cross-link to other documentation in the same project. Use relative links to
the file, like `../index.md`. (These are converted to HTML when the site is
rendered.)
### Anchor links
Relative linking enables crosslinks to work:
Each heading has an anchor link. For example, a topic with the title
`## This is an example` has the anchor `#this-is-an-example`.
- in Review Apps, local previews, and `/help`.
- when working on the documentation locally, so you can verify that they work as
early as possible in the process.
- in the GitLab user interface when browsing doc files in their respective
repositories. For example, the links displayed at
`https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/README.md`.
The first topic on a page (the `h1`) has an anchor link,
but do not use it. Link to the page instead.
To link to internal documentation:
If a heading has a [product tier badge](#product-tier-badges),
do not include it in the anchor link. For example, for the heading
`## This is an example **(FREE)**`, use the anchor `#this-is-an-example`.
- Use relative links to Markdown files in the same repository.
- Do not use absolute URLs or URLs from `docs.gitlab.com`.
- Use `../` to navigate to higher-level directories.
- Don't prepend `./` to links to files or directories. To link to a file in the
same directory or one of its sub-directories, use the syntax `path/to/file.md`.
- Don't link relative to root. For example, `/ee/user/gitlab_com/index.md`.
With Kramdown, you can add a custom ID to an HTML element, but these IDs
don't work in `/help`, so you should not use them.
Don't:
#### Changing links and titles
- `https://docs.gitlab.com/ee/administration/geo/replication/troubleshooting.html`
- `/ee/administration/geo/replication/troubleshooting.md`
- `./troubleshooting.md`
When you change a heading, the anchor link changes. To ensure you update
any related links, search these directories:
Do: `../../geo/replication/troubleshooting.md`
- `doc/*`
- `app/views/*`
- `ee/app/views/*`
- Always add the filename `file.md` at the end of the link with the `.md`
extension, not `.html`.
If you do not fix these links, the [`ui-docs-lint` job](../testing.md#ui-link-tests)
in your merge request fails.
Don't:
### Text for links
- `../../merge_requests/`
- `../../issues/tags.html`
- `../../issues/tags.html#stages`
Use descriptive text for links, rather than words like `here` or `this page.`
Do:
For example, instead of:
- `../../merge_requests/index.md`
- `../../issues/tags.md`
- `../../issues/tags.md#stages`
- `issues/tags.md`
- `For more information, see [this page](LINK).`
- `For more information, go [here](LINK).`
NOTE:
Using the Markdown extension is necessary for the [`/help`](../index.md#gitlab-help)
section of GitLab.
Use:
- `For more information, see [merge requests](LINK)`.
### Links to external documentation

View file

@ -1109,7 +1109,6 @@ profile increases as the number of tests increases.
|[`FUZZAPI_GRAPHQL_SCHEMA`](#graphql-schema) | A URL or filename for a GraphQL schema in JSON format. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352780) in GitLab 15.4. |
|[`FUZZAPI_POSTMAN_COLLECTION`](#postman-collection) | Postman Collection file. |
|[`FUZZAPI_POSTMAN_COLLECTION_VARIABLES`](#postman-variables) | Path to a JSON file to extract Postman variable values. The support for comma-separated (`,`) files was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356312) in GitLab 15.1. |
|[`FUZZAPI_POSTMAN_COLLECTION_VARIABLES`](#postman-variables) | Path to a JSON file to extract Postman variable values. |
|[`FUZZAPI_OVERRIDES_FILE`](#overrides) | Path to a JSON file containing overrides. |
|[`FUZZAPI_OVERRIDES_ENV`](#overrides) | JSON string containing headers to override. |
|[`FUZZAPI_OVERRIDES_CMD`](#overrides) | Overrides command. |

View file

@ -10,6 +10,8 @@ module ContainerRegistry
REGISTRY_FEATURES_HEADER = 'gitlab-container-registry-features'
REGISTRY_TAG_DELETE_FEATURE = 'tag_delete'
DEFAULT_TAGS_PAGE_SIZE = 10000
ALLOWED_REDIRECT_SCHEMES = %w[http https].freeze
REDIRECT_OPTIONS = {
clear_authorization_header: true,
@ -52,8 +54,11 @@ module ContainerRegistry
}
end
def repository_tags(name)
response_body faraday.get("/v2/#{name}/tags/list")
def repository_tags(name, page_size: DEFAULT_TAGS_PAGE_SIZE)
response = faraday.get("/v2/#{name}/tags/list") do |req|
req.params['n'] = page_size if Feature.enabled?(:container_registry_tags_list_default_page_size)
end
response_body(response)
end
def repository_manifest(name, reference)

View file

@ -394,7 +394,7 @@ module Gitlab
elsif user
user.can?(:read_project, project)
elsif ci?
true # allow CI (build without a user) for backwards compatibility
!Feature.enabled?(:ci_remove_userless_ci, project) # When disabled allow CI (build without a user) for backward compatibility
end || Guest.can?(:read_project, project)
end

View file

@ -423,6 +423,34 @@ RSpec.describe ContainerRegistry::Client do
end
end
describe '#repository_tags' do
let(:path) { 'repository/path' }
subject { client.repository_tags(path) }
before do
stub_container_registry_config(enabled: true, api_url: registry_api_url, key: 'spec/fixtures/x509_certificate_pk.key')
end
it 'returns a successful response' do
stub_registry_tags_list(query_params: { n: described_class::DEFAULT_TAGS_PAGE_SIZE }, tags: %w[t1 t2])
expect(subject).to eq('tags' => %w[t1 t2])
end
context 'with container_registry_tags_list_default_page_size disabled' do
before do
stub_feature_flags(container_registry_tags_list_default_page_size: false)
end
it 'returns a successful response' do
stub_registry_tags_list(tags: %w[t1 t2])
expect(subject).to eq('tags' => %w[t1 t2])
end
end
end
describe '.registry_info' do
subject { described_class.registry_info }
@ -458,6 +486,22 @@ RSpec.describe ContainerRegistry::Client do
)
end
def stub_registry_tags_list(query_params: {}, status: 200, tags: ['test_tag'])
url = "#{registry_api_url}/v2/#{path}/tags/list"
unless query_params.empty?
url += "?"
url += query_params.map { |k, v| "#{k}=#{v}" }.join(',')
end
stub_request(:get, url)
.with(headers: { 'Accept' => ContainerRegistry::Client::ACCEPTED_TYPES.join(', ') })
.to_return(
status: status,
body: Gitlab::Json.dump(tags: tags),
headers: { 'Content-Type' => 'application/json' })
end
def expect_new_faraday(times: 1, timeout: true)
request_options = timeout ? expected_faraday_request_options : nil
expect(Faraday)

View file

@ -8,7 +8,6 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures do
include AdminModeHelper
let(:user) { create(:user) }
let(:actor) { user }
let(:project) { create(:project, :repository) }
let(:repository_path) { "#{project.full_path}.git" }
@ -32,6 +31,17 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures do
end
end
shared_examples 'logs userless ci' do
it 'logs' do
expect(Gitlab::AppJsonLogger).to receive(:info).with(
message: 'Actor was :ci',
project_id: project.id
).once
pull_access_check
end
end
describe '#check with single protocols allowed' do
def disable_protocol(protocol)
allow(Gitlab::ProtocolAccess).to receive(:allowed?).with(protocol, project: project).and_return(false)
@ -144,21 +154,28 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures do
let(:actor) { :ci }
let(:authentication_abilities) { build_authentication_abilities }
it 'allows pull access' do
expect { pull_access_check }.not_to raise_error
it 'disallows pull access' do
expect { pull_access_check }.to raise_error(Gitlab::GitAccess::NotFoundError)
end
it 'does not block pushes with "not found"' do
expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:auth_upload])
end
it 'logs' do
expect(Gitlab::AppJsonLogger).to receive(:info).with(
message: 'Actor was :ci',
project_id: project.id
).once
context 'when ci_remove_userless_ci is disabled' do
before do
stub_feature_flags(ci_remove_userless_ci: false)
end
pull_access_check
it 'allows pull access' do
expect { pull_access_check }.not_to raise_error
end
it 'does not block pushes with "not found"' do
expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:auth_upload])
end
it_behaves_like 'logs userless ci'
end
end
@ -741,17 +758,16 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures do
describe 'generic CI (build without a user)' do
let(:actor) { :ci }
context 'pull code' do
it { expect { pull_access_check }.not_to raise_error }
specify { expect { pull_access_check }.to raise_error Gitlab::GitAccess::NotFoundError }
it 'logs' do
expect(Gitlab::AppJsonLogger).to receive(:info).with(
message: 'Actor was :ci',
project_id: project.id
).once
pull_access_check
context 'when ci_remove_userless_ci disabled' do
before do
stub_feature_flags(ci_remove_userless_ci: false)
end
specify { expect { pull_access_check }.not_to raise_error }
it_behaves_like 'logs userless ci'
end
end
end

View file

@ -17,7 +17,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do
api_url: 'http://registry.gitlab',
host_port: 'registry.gitlab')
stub_request(:get, 'http://registry.gitlab/v2/group/test/my_image/tags/list')
stub_request(:get, "http://registry.gitlab/v2/group/test/my_image/tags/list?n=#{::ContainerRegistry::Client::DEFAULT_TAGS_PAGE_SIZE}")
.with(headers: { 'Accept' => ContainerRegistry::Client::ACCEPTED_TYPES.join(', ') })
.to_return(
status: 200,

View file

@ -880,29 +880,51 @@ RSpec.describe 'Git HTTP requests' do
let(:path) { "#{project.full_path}.git" }
let(:env) { { user: 'gitlab-ci-token', password: build.token } }
it_behaves_like 'pulls are allowed'
it 'rejects pulls' do
download(path, **env) do |response|
expect(response).to have_gitlab_http_status(:not_found)
end
end
# A non-401 here is not an information leak since the system is
# "authenticated" as CI using the correct token. It does not have
# push access, so pushes should be rejected as forbidden, and giving
# a reason is fine.
#
# We know for sure it is not an information leak since pulls using
# the build token must be allowed.
it "rejects pushes with 403 Forbidden" do
it 'rejects pushes' do
push_get(path, **env)
expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:auth_upload))
end
# We are "authenticated" as CI using a valid token here. But we are
# not authorized to see any other project, so return "not found".
it "rejects pulls for other project with 404 Not Found" do
clone_get("#{other_project.full_path}.git", **env)
context 'when ci_remove_userless_ci disabled' do
before do
stub_feature_flags(ci_remove_userless_ci: false)
end
expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
it_behaves_like 'pulls are allowed'
# A non-401 here is not an information leak since the system is
# "authenticated" as CI using the correct token. It does not have
# push access, so pushes should be rejected as forbidden, and giving
# a reason is fine.
#
# We know for sure it is not an information leak since pulls using
# the build token must be allowed.
it "rejects pushes with 403 Forbidden" do
push_get(path, **env)
expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:auth_upload))
end
# We are "authenticated" as CI using a valid token here. But we are
# not authorized to see any other project, so return "not found".
it "rejects pulls for other project with 404 Not Found" do
clone_get("#{other_project.full_path}.git", **env)
expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
end
end
def pull
download(path, **env)
end
end
@ -1498,29 +1520,47 @@ RSpec.describe 'Git HTTP requests' do
let(:path) { "#{project.full_path}.git" }
let(:env) { { user: 'gitlab-ci-token', password: build.token } }
it_behaves_like 'pulls are allowed'
it 'rejects pulls' do
download(path, **env) do |response|
expect(response).to have_gitlab_http_status(:not_found)
end
end
# A non-401 here is not an information leak since the system is
# "authenticated" as CI using the correct token. It does not have
# push access, so pushes should be rejected as forbidden, and giving
# a reason is fine.
#
# We know for sure it is not an information leak since pulls using
# the build token must be allowed.
it "rejects pushes with 403 Forbidden" do
it 'rejects pushes' do
push_get(path, **env)
expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:auth_upload))
end
# We are "authenticated" as CI using a valid token here. But we are
# not authorized to see any other project, so return "not found".
it "rejects pulls for other project with 404 Not Found" do
clone_get("#{other_project.full_path}.git", **env)
context 'when ci_remove_userless_ci is disabled' do
before do
stub_feature_flags(ci_remove_userless_ci: false)
end
expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
it_behaves_like 'pulls are allowed'
# A non-401 here is not an information leak since the system is
# "authenticated" as CI using the correct token. It does not have
# push access, so pushes should be rejected as forbidden, and giving
# a reason is fine.
#
# We know for sure it is not an information leak since pulls using
# the build token must be allowed.
it "rejects pushes with 403 Forbidden" do
push_get(path, **env)
expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:auth_upload))
end
# We are "authenticated" as CI using a valid token here. But we are
# not authorized to see any other project, so return "not found".
it "rejects pulls for other project with 404 Not Found" do
clone_get("#{other_project.full_path}.git", **env)
expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
end
end
end

View file

@ -19,7 +19,7 @@ RSpec.describe PipelineSerializer do
end
context 'when a single object is being serialized' do
let(:resource) { create(:ci_empty_pipeline, project: project) }
let(:resource) { build_stubbed(:ci_empty_pipeline, project: project) }
it 'serializers the pipeline object' do
expect(subject[:id]).to eq resource.id
@ -27,10 +27,11 @@ RSpec.describe PipelineSerializer do
end
context 'when multiple objects are being serialized' do
let(:resource) { create_list(:ci_pipeline, 2, project: project) }
let(:resource) { Array.new(2) { build_stubbed(:ci_pipeline, project: project) } }
it 'serializers the array of pipelines' do
expect(subject).not_to be_empty
expect(subject.size).to eq(2)
end
end
end
@ -41,8 +42,7 @@ RSpec.describe PipelineSerializer do
let(:query) { {} }
let(:serializer) do
described_class.new(current_user: user)
.with_pagination(request, response)
described_class.new(current_user: user, project: project).with_pagination(request, response)
end
it 'created a paginated serializer' do
@ -67,7 +67,7 @@ RSpec.describe PipelineSerializer do
context 'when a single pipeline object is present in relation' do
before do
create(:ci_empty_pipeline)
create(:ci_empty_pipeline, project: project)
end
it 'serializes pipeline relation' do
@ -77,7 +77,7 @@ RSpec.describe PipelineSerializer do
context 'when a multiple pipeline objects are being serialized' do
before do
create_list(:ci_empty_pipeline, 3)
create_list(:ci_empty_pipeline, 3, project: project)
end
it 'serializes appropriate number of objects' do
@ -100,28 +100,28 @@ RSpec.describe PipelineSerializer do
let!(:merge_request_1) do
create(:merge_request,
:with_detached_merge_request_pipeline,
target_project: project,
target_branch: 'master',
source_project: project,
source_branch: 'feature')
:with_detached_merge_request_pipeline,
target_project: project,
target_branch: 'master',
source_project: project,
source_branch: 'feature')
end
let!(:merge_request_2) do
create(:merge_request,
:with_detached_merge_request_pipeline,
target_project: project,
target_branch: 'master',
source_project: project,
source_branch: '2-mb-file')
:with_detached_merge_request_pipeline,
target_project: project,
target_branch: 'master',
source_project: project,
source_branch: '2-mb-file')
end
before do
before_all do
project.add_developer(user)
end
it 'includes merge requests information' do
expect(subject.all? { |entry| entry[:merge_request].present? }).to be_truthy
expect(subject).to be_all { |entry| entry[:merge_request].present? }
end
it 'preloads related merge requests' do
@ -138,7 +138,8 @@ RSpec.describe PipelineSerializer do
let(:resource) { Ci::Pipeline.all }
before do
# Create pipelines only once and change their attributes if needed.
before_all do
# Since RequestStore.active? is true we have to allow the
# gitaly calls in this block
# Issue: https://gitlab.com/gitlab-org/gitlab-foss/issues/37772
@ -151,8 +152,6 @@ RSpec.describe PipelineSerializer do
end
context 'with the same ref' do
let(:ref) { 'feature' }
it 'verifies number of queries', :request_store do
recorded = ActiveRecord::QueryRecorder.new { subject }
expected_queries = Gitlab.ee? ? 33 : 30
@ -163,10 +162,11 @@ RSpec.describe PipelineSerializer do
end
context 'with different refs' do
def ref
@sequence ||= 0
@sequence += 1
"feature-#{@sequence}"
before do
# rubocop:disable Rails/SkipsModelValidations
Ci::Pipeline.update_all(%(ref = 'feature-' || id))
Ci::Build.update_all(%(ref = 'feature-' || stage_id))
# rubocop:enable Rails/SkipsModelValidations
end
it 'verifies number of queries', :request_store do
@ -184,8 +184,6 @@ RSpec.describe PipelineSerializer do
end
context 'with triggered pipelines' do
let(:ref) { 'feature' }
before do
pipeline_1 = create(:ci_pipeline)
build_1 = create(:ci_build, pipeline: pipeline_1)
@ -210,8 +208,6 @@ RSpec.describe PipelineSerializer do
end
context 'with build environments' do
let(:ref) { 'feature' }
let_it_be(:production) { create(:environment, :production, project: project) }
let_it_be(:staging) { create(:environment, :staging, project: project) }
@ -222,13 +218,11 @@ RSpec.describe PipelineSerializer do
create(:ci_build, :scheduled, pipeline: pipeline, environment: production.name)
create(:ci_build, :scheduled, pipeline: pipeline, environment: staging.name)
expect { subject }.not_to exceed_query_limit(1).for_query /SELECT "environments".*/
expect { subject }.not_to exceed_query_limit(1).for_query(/SELECT "environments".*/)
end
end
context 'with scheduled and manual builds' do
let(:ref) { 'feature' }
before do
create(:ci_build, :scheduled, pipeline: resource.first)
create(:ci_build, :scheduled, pipeline: resource.second)
@ -238,7 +232,7 @@ RSpec.describe PipelineSerializer do
it 'sends at most one metadata query for each type of build', :request_store do
# 1 for the existing failed builds and 2 for the added scheduled and manual builds
expect { subject }.not_to exceed_query_limit(1 + 2).for_query /SELECT "ci_builds_metadata".*/
expect { subject }.not_to exceed_query_limit(1 + 2).for_query(/SELECT "ci_builds_metadata".*/)
end
end
@ -246,25 +240,25 @@ RSpec.describe PipelineSerializer do
create(:ci_empty_pipeline,
project: project,
status: status,
ref: ref).tap do |pipeline|
Ci::Build::AVAILABLE_STATUSES.each do |status|
create_build(pipeline, status, status)
ref: 'feature').tap do |pipeline|
Ci::Build::AVAILABLE_STATUSES.each do |build_status|
create_build(pipeline, status, build_status)
end
end
end
def create_build(pipeline, stage, status)
create(:ci_build, :tags, :triggered, :artifacts,
pipeline: pipeline, stage: stage,
name: stage, status: status, ref: pipeline.ref)
pipeline: pipeline, stage: stage,
name: stage, status: status, ref: pipeline.ref)
end
end
end
describe '#represent_status' do
context 'when represents only status' do
let(:resource) { create(:ci_pipeline) }
let(:status) { resource.detailed_status(double('user')) }
let(:resource) { build_stubbed(:ci_pipeline) }
let(:status) { resource.detailed_status(instance_double('User')) }
subject { serializer.represent_status(resource) }

View file

@ -9632,7 +9632,6 @@
- './spec/serializers/personal_access_token_entity_spec.rb'
- './spec/serializers/personal_access_token_serializer_spec.rb'
- './spec/serializers/pipeline_details_entity_spec.rb'
- './spec/serializers/pipeline_serializer_spec.rb'
- './spec/serializers/project_access_token_entity_spec.rb'
- './spec/serializers/project_access_token_serializer_spec.rb'
- './spec/serializers/project_import_entity_spec.rb'