Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
29f6c0bff8
commit
68964241ec
19 changed files with 279 additions and 209 deletions
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
1
db/schema_migrations/20220919041604
Normal file
1
db/schema_migrations/20220919041604
Normal file
|
@ -0,0 +1 @@
|
|||
a4115d5542d236a030db180363cf2c816ff68cd2c2a54e74a6b3ba916a40816e
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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. |
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in a new issue