diff options
-rw-r--r-- | .gitlab/ci/qa-common/rules.gitlab-ci.yml | 4 | ||||
-rw-r--r-- | .gitlab/ci/rules.gitlab-ci.yml | 4 | ||||
-rw-r--r-- | .gitlab/ci/test-on-gdk/main.gitlab-ci.yml | 100 | ||||
-rw-r--r-- | app/finders/packages/packages_finder.rb | 1 | ||||
-rw-r--r-- | app/graphql/resolvers/packages_base_resolver.rb | 5 | ||||
-rw-r--r-- | doc/administration/gitaly/recovery.md | 54 | ||||
-rw-r--r-- | doc/administration/settings/jira_cloud_app.md | 20 | ||||
-rw-r--r-- | doc/api/graphql/reference/index.md | 2 | ||||
-rw-r--r-- | doc/api/packages.md | 2 | ||||
-rw-r--r-- | doc/development/api_graphql_styleguide.md | 11 | ||||
-rw-r--r-- | doc/integration/jira/connect-app.md | 8 | ||||
-rw-r--r-- | lib/api/group_packages.rb | 6 | ||||
-rw-r--r-- | lib/api/project_packages.rb | 4 | ||||
-rw-r--r-- | spec/features/groups/container_registry_spec.rb | 6 | ||||
-rw-r--r-- | spec/features/groups/dependency_proxy_spec.rb | 8 | ||||
-rw-r--r-- | spec/requests/api/group_packages_spec.rb | 14 | ||||
-rw-r--r-- | spec/requests/api/project_packages_spec.rb | 12 | ||||
-rw-r--r-- | spec/support/shared_examples/graphql/resolvers/packages_resolvers_shared_examples.rb | 6 |
18 files changed, 196 insertions, 71 deletions
diff --git a/.gitlab/ci/qa-common/rules.gitlab-ci.yml b/.gitlab/ci/qa-common/rules.gitlab-ci.yml index c593ec4ccfb..7fa66fa4384 100644 --- a/.gitlab/ci/qa-common/rules.gitlab-ci.yml +++ b/.gitlab/ci/qa-common/rules.gitlab-ci.yml @@ -14,6 +14,10 @@ .spec-file-specified: &spec-file-specified if: $QA_TESTS =~ /_spec\.rb/ +# code pattern changes +.code-pattern-changes: &code-pattern-changes + if: $MR_CODE_PATTERNS == "true" + # Specs directory specified .spec-directory-specified: &spec-directory-specified if: $QA_TESTS != "" && $QA_TESTS !~ /_spec\.rb/ diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 4c95c3b6906..a6eb019cc3f 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -1624,6 +1624,10 @@ - <<: *if-dot-com-gitlab-org-and-security-merge-request-and-qa-tests-specified changes: *code-patterns - <<: *if-merge-request + changes: *code-patterns + variables: + MR_CODE_PATTERNS: "true" + - <<: *if-merge-request changes: *code-qa-patterns # Includes all CI changes - <<: *if-force-ci when: manual diff --git a/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml b/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml index b8db2aa8957..d708ab21908 100644 --- a/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml +++ b/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml @@ -3,6 +3,55 @@ include: - local: .gitlab/ci/qa-common/main.gitlab-ci.yml - local: .gitlab/ci/qa-common/rules.gitlab-ci.yml - local: .gitlab/ci/qa-common/variables.gitlab-ci.yml + - component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@7.3.0" + inputs: + job_name: "e2e-test-report" + job_stage: "report" + aws_access_key_id_variable_name: "QA_ALLURE_AWS_ACCESS_KEY_ID" + aws_secret_access_key_variable_name: "QA_ALLURE_AWS_SECRET_ACCESS_KEY" + gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE" + allure_results_glob: "qa/tmp/allure-results" + allure_ref_slug: "${CI_COMMIT_REF_SLUG}" + allure_project_path: "${CI_PROJECT_PATH}" + allure_merge_request_iid: "${CI_MERGE_REQUEST_IID}" + allure_job_name: "${QA_RUN_TYPE}" + +# code pattern changes +.code-pattern-changes: &code-pattern-changes + if: $MR_CODE_PATTERNS == "true" + +# Run all tests when QA framework changes present, full suite execution is explicitly enabled or a feature flag file is removed +.qa-run-all-tests: &qa-run-all-tests + if: $QA_FRAMEWORK_CHANGES == "true" || $QA_RUN_ALL_TESTS == "true" || $QA_RUN_ALL_E2E_LABEL == "true" || $QA_FEATURE_FLAGS =~ /deleted/ + +variables: + COLORIZED_LOGS: "true" + GIT_DEPTH: "20" + GIT_STRATEGY: "clone" # 'GIT_STRATEGY: clone' optimizes the pack-objects cache hit ratio + GIT_SUBMODULE_STRATEGY: "none" + +.rules:gdk:qa-selective: + rules: + - <<: *code-pattern-changes + when: never + - !reference [.rules:test:qa-selective, rules] + - if: $QA_SUITES =~ /Test::Instance::Blocking/ + +.rules:gdk:qa-parallel: + rules: + - *code-pattern-changes + - !reference [.rules:test:qa-parallel, rules] + - if: $QA_SUITES =~ /Test::Instance::Blocking/ + +.rules:gdk:qa-smoke: + rules: + - <<: *code-pattern-changes + variables: + QA_TESTS: "" + - <<: *qa-run-all-tests + variables: + QA_TESTS: "" + - if: $QA_SUITES =~ /Test::Instance::Smoke/ .gdk-qa-base: image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}:bundler-2.3-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23 @@ -70,27 +119,10 @@ include: expire_in: 7 days when: always -# Take the existing GDK docker image and reconfigure it with Postgres load -# balancing. Adding 5s lag to 1 of the replicas to validate robustness of -# the load balancer. -.gdk-with-load-balancer-setup: - before_script: - - !reference [".gdk-qa-base", "before_script"] - - | - docker exec gdk bash -c " - gdk config set postgresql.replica.enabled true &&\ - gdk config set postgresql.replica_2.enabled true &&\ - gdk config set load_balancing.enabled true &&\ - gdk reconfigure &&\ - gdk restart" - download-knapsack-report: extends: - .download-knapsack-report - .rules:download-knapsack - needs: - - pipeline: $PARENT_PIPELINE_ID - job: build-qa-image cache-gems: extends: @@ -103,23 +135,33 @@ cache-gems: script: - cd qa && bundle install +# Take the existing GDK docker image and reconfigure it with Postgres load +# balancing. Adding 5s lag to 1 of the replicas to validate robustness of +# the load balancer. +.gdk-with-load-balancer-setup: + before_script: + - !reference [".gdk-qa-base", "before_script"] + - | + docker exec gdk bash -c " + gdk config set postgresql.replica.enabled true &&\ + gdk config set postgresql.replica_2.enabled true &&\ + gdk config set load_balancing.enabled true &&\ + gdk reconfigure &&\ + gdk restart" + download-fast-quarantine-report: extends: - .download-fast-quarantine-report - .rules:download-fast-quarantine-report -# ========================================== -# Test stage -# ========================================== gdk-qa-smoke: extends: - .gdk-qa-base - .gitlab-qa-report + - .rules:gdk:qa-smoke variables: QA_SCENARIO: Test::Instance::Smoke QA_RUN_TYPE: gdk-qa-smoke - rules: - - when: always gdk-qa-smoke-with-load-balancer: extends: @@ -143,12 +185,20 @@ gdk-qa-reliable: - .gdk-qa-base - .gitlab-qa-report - .parallel + - .rules:gdk:qa-parallel variables: QA_SCENARIO: Test::Instance::Blocking QA_RUN_TYPE: gdk-qa-blocking parallel: 10 - rules: - - when: always + +gdk-qa-reliable-selective: + extends: + - .gdk-qa-base + - .gitlab-qa-report + - .rules:gdk:qa-selective + variables: + QA_SCENARIO: Test::Instance::Blocking + QA_RUN_TYPE: gdk-qa-blocking gdk-qa-reliable-with-load-balancer: extends: @@ -184,8 +234,6 @@ gdk-qa-non-blocking: # ========================================== e2e-test-report: extends: .rules:report:allure-report - variables: - ALLURE_REPORT_RESULTS_GLOB: "qa/tmp/allure-results" upload-knapsack-report: extends: diff --git a/app/finders/packages/packages_finder.rb b/app/finders/packages/packages_finder.rb index 31fbbfb7937..8fe1a73a030 100644 --- a/app/finders/packages/packages_finder.rb +++ b/app/finders/packages/packages_finder.rb @@ -22,6 +22,7 @@ module Packages packages = filter_by_package_type(packages) packages = filter_by_package_name(packages) packages = filter_by_status(packages) + packages = filter_by_package_version(packages) order_packages(packages) end diff --git a/app/graphql/resolvers/packages_base_resolver.rb b/app/graphql/resolvers/packages_base_resolver.rb index 7d153d16910..084fbc23156 100644 --- a/app/graphql/resolvers/packages_base_resolver.rb +++ b/app/graphql/resolvers/packages_base_resolver.rb @@ -19,6 +19,11 @@ module Resolvers required: false, default_value: nil + argument :package_version, GraphQL::Types::String, + description: 'Filter a package by version.', + required: false, + default_value: nil + argument :status, Types::Packages::PackageStatusEnum, description: 'Filter a package by status.', required: false, diff --git a/doc/administration/gitaly/recovery.md b/doc/administration/gitaly/recovery.md index 45bde083a1a..6779823c941 100644 --- a/doc/administration/gitaly/recovery.md +++ b/doc/administration/gitaly/recovery.md @@ -15,12 +15,17 @@ You can add and replace Gitaly nodes on a Gitaly Cluster. ### Add new Gitaly nodes -To add a new Gitaly node to a Gitaly Cluster that has [replication factor](praefect.md#configure-replication-factor): +The steps to add a new Gitaly node to a Gitaly Cluster depend on whether a [custom replication factor](praefect.md#configure-replication-factor) is set. -- Set, set the [replication factor](praefect.md#configure-replication-factor) for each repository using `set-replication-factor` Praefect command. New repositories are - replicated based on [replication factor](praefect.md#configure-replication-factor). Praefect doesn't automatically replicate existing repositories to the new Gitaly node. -- Not set, add the new node in your [Praefect configuration](praefect.md#praefect) under `praefect['virtual_storages']`. Praefect automatically replicates all data to any - new Gitaly node added to the configuration. +#### Custom replication factor + +If a custom replication factor is set, set the [replication factor](praefect.md#configure-replication-factor) for each repository using the +`set-replication-factor` Praefect command. New repositories are replicated based on the [replication factor](praefect.md#configure-replication-factor). Praefect doesn't automatically replicate existing repositories to the new Gitaly node. + +#### Default replication factor + +If the default replication factor is used, add the new node in your [Praefect configuration](praefect.md#praefect) under `praefect['virtual_storages']`. +Praefect automatically replicates all data to any new Gitaly node added to the configuration. ### Replace an existing Gitaly node @@ -33,32 +38,37 @@ To use the same name for the replacement node, use [repository verifier](praefec #### With a node with a different name -To use a different name for the replacement node for a Gitaly Cluster that has [replication factor](praefect.md#configure-replication-factor): +The steps use a different name for the replacement node for a Gitaly Cluster depend on if a [custom replication factor](praefect.md#configure-replication-factor) +is set. -- Set, use [`praefect set-replication-factor`](praefect.md#configure-replication-factor) to set the replication factor per repository again to get new storage assigned. - For example: +##### Custom replication factor set - ```shell - $ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage default -relative-path @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git -replication-factor 2 +If a custom replication factor is set, use [`praefect set-replication-factor`](praefect.md#configure-replication-factor) to set the replication factor per repository again to get new storage assigned. For example: - current assignments: gitaly-1, gitaly-2 - ``` +```shell +$ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage default -relative-path @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git -replication-factor 2 + +current assignments: gitaly-1, gitaly-2 +``` + +To reassign all repositories from the old storage to the new one, after configuring the new Gitaly node: - To reassign all repositories from the old storage to the new one, after configuring the new Gitaly node: +1. Connect to Praefect database: - 1. Connect to Praefect database: + ```shell + /opt/gitlab/embedded/bin/psql -h <psql host> -U <user> -d <database name> + ``` - ```shell - /opt/gitlab/embedded/bin/psql -h <psql host> -U <user> -d <database name> - ``` +1. Update the `repository_assignments` table to replace the old Gitaly node name (for example, `old-gitaly`) with the new Gitaly node name + (for example, `new-gitaly`): - 1. Update `repository_assignments` table to replace the old Gitaly node name (for example, `old-gitaly`) with the new Gitaly node name (for example, `new-gitaly`): + ```sql + UPDATE repository_assignments SET storage='new-gitaly' WHERE storage='old-gitaly'; + ``` - ```sql - UPDATE repository_assignments SET storage='new-gitaly' WHERE storage='old-gitaly'; - ``` +##### Default replication factor -- Not set, replace the node in the configuration. The old node's state remains in the Praefect database but it is ignored. +If the default replication factor is used, replace the node in the configuration. The old node's state remains in the Praefect database but it is ignored. ## Primary node failure diff --git a/doc/administration/settings/jira_cloud_app.md b/doc/administration/settings/jira_cloud_app.md index f4f1db3617e..7a53a67ec86 100644 --- a/doc/administration/settings/jira_cloud_app.md +++ b/doc/administration/settings/jira_cloud_app.md @@ -45,6 +45,17 @@ To create an OAuth application on your self-managed instance: 1. Paste the **Application ID** value into **Jira Connect Application ID**. 1. Select **Save changes**. +## Jira user requirements + +You must ensure that the Jira user that is used to setup the GitLab for Jira Cloud app is a member of the Site Administrators (`site-admins`) group in your +[Atlassian organization](https://admin.atlassian.com): + +1. If you don't have a `site-admins` group in your Atlassian organization, [create the group](https://support.atlassian.com/user-management/docs/create-groups/). +1. If not already a member, [add your Jira user as a member](https://support.atlassian.com/user-management/docs/edit-a-group/) of the `site-admins` group. + +If you have customized your global permissions in Jira, you might also need to grant the +[`Browse users and groups` permission](https://confluence.atlassian.com/jirakb/unable-to-browse-for-users-and-groups-120521888.html) to the Jira user. + ## Connect the GitLab for Jira Cloud app > Introduced in GitLab 15.7. @@ -76,6 +87,7 @@ With this method: - Set up an internet-facing reverse proxy in front of your self-managed instance. To secure this proxy further, only allow inbound traffic from [Atlassian IP addresses](https://support.atlassian.com/organization-administration/docs/ip-addresses-and-domains-for-atlassian-cloud-products/#Outgoing-Connections). - Add [GitLab IP addresses](../../user/gitlab_com/index.md#ip-range) to the allowlist of your firewall. +- The Jira user that installs and configures the GitLab for Jira Cloud app must meet certain [requirements](#jira-user-requirements). ### Set up your instance @@ -144,6 +156,7 @@ To support your self-managed instance with Jira Cloud, do one of the following: - The instance must be publicly available. - You must set up [OAuth authentication](#set-up-oauth-authentication). +- The Jira user that installs and configures the GitLab for Jira Cloud app must meet certain [requirements](#jira-user-requirements). ### Install the app in development mode @@ -349,9 +362,6 @@ When you check the browser console, you might see the following message: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://gitlab.example.com/-/jira_connect/oauth_application_id. (Reason: CORS header 'Access-Control-Allow-Origin' missing). Status code: 403. ``` -`403` status code is returned if: - -- The user information cannot be fetched from Jira. -- The authenticated Jira user does not have [site administrator](https://support.atlassian.com/user-management/docs/give-users-admin-permissions/#Make-someone-a-site-admin) access. +`403` status code is returned if the user information cannot be fetched from Jira because of insufficient permissions. -To resolve this issue, ensure the authenticated user is a Jira site administrator and try again. +To resolve this issue, ensure that the Jira user that installs and configures the GitLab for Jira Cloud app meets certain [requirements](#jira-user-requirements). diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index fe5ec23dcaf..7a37881d208 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -18884,6 +18884,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="grouppackagesincludeversionless"></a>`includeVersionless` | [`Boolean`](#boolean) | Include versionless packages. | | <a id="grouppackagespackagename"></a>`packageName` | [`String`](#string) | Search a package by name. | | <a id="grouppackagespackagetype"></a>`packageType` | [`PackageTypeEnum`](#packagetypeenum) | Filter a package by type. | +| <a id="grouppackagespackageversion"></a>`packageVersion` | [`String`](#string) | Filter a package by version. | | <a id="grouppackagessort"></a>`sort` | [`PackageGroupSort`](#packagegroupsort) | Sort packages by this criteria. | | <a id="grouppackagesstatus"></a>`status` | [`PackageStatus`](#packagestatus) | Filter a package by status. | @@ -23826,6 +23827,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="projectpackagesincludeversionless"></a>`includeVersionless` | [`Boolean`](#boolean) | Include versionless packages. | | <a id="projectpackagespackagename"></a>`packageName` | [`String`](#string) | Search a package by name. | | <a id="projectpackagespackagetype"></a>`packageType` | [`PackageTypeEnum`](#packagetypeenum) | Filter a package by type. | +| <a id="projectpackagespackageversion"></a>`packageVersion` | [`String`](#string) | Filter a package by version. | | <a id="projectpackagessort"></a>`sort` | [`PackageSort`](#packagesort) | Sort packages by this criteria. | | <a id="projectpackagesstatus"></a>`status` | [`PackageStatus`](#packagestatus) | Filter a package by status. | diff --git a/doc/api/packages.md b/doc/api/packages.md index a378be26a24..0a2bfa3c30f 100644 --- a/doc/api/packages.md +++ b/doc/api/packages.md @@ -30,6 +30,7 @@ GET /projects/:id/packages | `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. | | `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, `helm`, `terraform_module`, or `golang`. (_Introduced in GitLab 12.9_) | `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_Introduced in GitLab 12.9_) +| `package_version` | string | no | Filter the project packages by version. (_[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/349065) in GitLab 16.6_) | `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_) | `status` | string | no | Filter the returned packages by status. One of `default` (default), `hidden`, `processing`, `error`, or `pending_destruction`. (_Introduced in GitLab 13.9_) @@ -97,6 +98,7 @@ GET /groups/:id/packages | `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. | | `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, `helm`, or `golang`. (_Introduced in GitLab 12.9_) | | `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30980) in GitLab 13.0_) +| `package_version` | string | no | Filter the returned packages by version. (_[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/349065) in GitLab 16.6_) | `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_) | `status` | string | no | Filter the returned packages by status. One of `default` (default), `hidden`, `processing`, `error`, or `pending_destruction`. (_Introduced in GitLab 13.9_) diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md index bb685c30631..318f9bed6d3 100644 --- a/doc/development/api_graphql_styleguide.md +++ b/doc/development/api_graphql_styleguide.md @@ -154,11 +154,14 @@ developers must familiarize themselves with our [Deprecation and Removal process Breaking changes are: - Removing or renaming a field, argument, enum value, or mutation. -- Changing the type or type name of an argument. This is because the type of an argument +- Changing the type or type name of an argument. The type of an argument is declared by the client when [using variables](https://graphql.org/learn/queries/#variables), - and queries with the old type name would be rejected by the API. -- Changing the _scalar type_ of a field or enum value. Object types can be changed so long as all - scalar type fields of the object remain the same. + and a change would cause a query using the old type name to be rejected by the API. +- Changing the [_scalar type_](https://graphql.org/learn/schema/#scalar-types) of a field or enum + value where it results in a change to how the value serializes to JSON. + For example, a change from a JSON String to a JSON Number, or a change to how a String is formatted. + A change to another [_object type_](https://graphql.org/learn/schema/#object-types-and-fields) can be + allowed so long as all scalar type fields of the object continue to serialize in the same way. - Raising the [complexity](#max-complexity) of a field or complexity multipliers in a resolver. - Changing a field from being _not_ nullable (`null: false`) to nullable (`null: true`), as discussed in [Nullable fields](#nullable-fields). diff --git a/doc/integration/jira/connect-app.md b/doc/integration/jira/connect-app.md index 4f0adb2771a..78cfc406d19 100644 --- a/doc/integration/jira/connect-app.md +++ b/doc/integration/jira/connect-app.md @@ -107,9 +107,7 @@ After you connect the GitLab for Jira Cloud app, you might get this error: Failed to link group. Please try again. ``` -`403` status code is returned if: +`403` status code is returned if the user information cannot be fetched from Jira due to insufficient permissions. -- The user information cannot be fetched from Jira. -- The authenticated Jira user does not have [site administrator](https://support.atlassian.com/user-management/docs/give-users-admin-permissions/#Make-someone-a-site-admin) access. - -To resolve this issue, ensure the authenticated user is a Jira site administrator and try again. +To resolve this issue, ensure that the Jira user that installs and configures the GitLab for Jira Cloud app meets certain +[requirements](../../administration/settings/jira_cloud_app.md#jira-user-requirements). diff --git a/lib/api/group_packages.rb b/lib/api/group_packages.rb index c2b4cbf732f..b363f59b7ad 100644 --- a/lib/api/group_packages.rb +++ b/lib/api/group_packages.rb @@ -47,6 +47,9 @@ module API optional :package_name, type: String, desc: 'Return packages with this name' + optional :package_version, + type: String, + desc: 'Return packages with this version' optional :include_versionless, type: Boolean, desc: 'Returns packages without a version' @@ -60,7 +63,8 @@ module API current_user, user_group, declared(params).slice( - :exclude_subgroups, :order_by, :sort, :package_type, :package_name, :include_versionless, :status + :exclude_subgroups, :order_by, :sort, :package_type, :package_name, + :package_version, :include_versionless, :status ) ).execute diff --git a/lib/api/project_packages.rb b/lib/api/project_packages.rb index 6b2ba41f013..7f531525870 100644 --- a/lib/api/project_packages.rb +++ b/lib/api/project_packages.rb @@ -46,6 +46,8 @@ module API desc: 'Return packages of a certain type' optional :package_name, type: String, desc: 'Return packages with this name' + optional :package_version, type: String, + desc: 'Return packages with this version' optional :include_versionless, type: Boolean, desc: 'Returns packages without a version' optional :status, type: String, values: Packages::Package.statuses.keys, @@ -55,7 +57,7 @@ module API get ':id/packages' do packages = ::Packages::PackagesFinder.new( user_project, - declared_params.slice(:order_by, :sort, :package_type, :package_name, :include_versionless, :status) + declared_params.slice(:order_by, :sort, :package_type, :package_name, :package_version, :include_versionless, :status) ).execute present paginate(packages), with: ::API::Entities::Package, user: current_user, namespace: user_project.namespace diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb index 953a8e27547..65edeb0798f 100644 --- a/spec/features/groups/container_registry_spec.rb +++ b/spec/features/groups/container_registry_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Container Registry', :js, feature_category: :container_registry do - let(:user) { create(:user, :no_super_sidebar) } + let(:user) { create(:user) } let(:group) { create(:group) } let(:project) { create(:project, namespace: group) } @@ -28,8 +28,8 @@ RSpec.describe 'Container Registry', :js, feature_category: :container_registry it 'sidebar menu is open' do visit_container_registry - sidebar = find('.nav-sidebar') - expect(sidebar).to have_link _('Container Registry') + expect(page).to have_active_navigation('Deploy') + expect(page).to have_active_sub_navigation('Container Registry') end context 'when there are no image repositories' do diff --git a/spec/features/groups/dependency_proxy_spec.rb b/spec/features/groups/dependency_proxy_spec.rb index 2d4f6d4fbf2..12c480a46b0 100644 --- a/spec/features/groups/dependency_proxy_spec.rb +++ b/spec/features/groups/dependency_proxy_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe 'Group Dependency Proxy', feature_category: :dependency_proxy do - let(:owner) { create(:user, :no_super_sidebar) } - let(:reporter) { create(:user, :no_super_sidebar) } + let(:owner) { create(:user) } + let(:reporter) { create(:user) } let(:group) { create(:group) } let(:path) { group_dependency_proxy_path(group) } let(:settings_path) { group_settings_packages_and_registries_path(group) } @@ -36,8 +36,8 @@ RSpec.describe 'Group Dependency Proxy', feature_category: :dependency_proxy do it 'sidebar menu is open' do visit path - sidebar = find('.nav-sidebar') - expect(sidebar).to have_link _('Dependency Proxy') + expect(page).to have_active_navigation('Operate') + expect(page).to have_active_sub_navigation('Dependency Proxy') end it 'toggles defaults to enabled' do diff --git a/spec/requests/api/group_packages_spec.rb b/spec/requests/api/group_packages_spec.rb index 0b4f6130132..84c72edd18c 100644 --- a/spec/requests/api/group_packages_spec.rb +++ b/spec/requests/api/group_packages_spec.rb @@ -137,6 +137,20 @@ RSpec.describe API::GroupPackages, feature_category: :package_registry do it_behaves_like 'filters on each package_type', is_project: false + context 'filtering on package_version' do + include_context 'package filter context' + + let!(:package) { create(:nuget_package, project: project, version: '2.0.4') } + + it 'returns the versioned package' do + url = group_filter_url(:version, '2.0.4') + get api(url, user) + + expect(json_response.length).to eq(1) + expect(json_response.first['version']).to eq(package.version) + end + end + context 'does not accept non supported package_type value' do include_context 'package filter context' diff --git a/spec/requests/api/project_packages_spec.rb b/spec/requests/api/project_packages_spec.rb index 219c748c9a6..c945db0b46d 100644 --- a/spec/requests/api/project_packages_spec.rb +++ b/spec/requests/api/project_packages_spec.rb @@ -197,6 +197,18 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do end end + context 'filtering on package_version' do + include_context 'package filter context' + + it 'returns the versioned package' do + url = package_filter_url(:version, '2.0.4') + get api(url, user) + + expect(json_response.length).to eq(1) + expect(json_response.first['version']).to eq(package2.version) + end + end + it_behaves_like 'with versionless packages' it_behaves_like 'with status param' it_behaves_like 'does not cause n^2 queries' diff --git a/spec/support/shared_examples/graphql/resolvers/packages_resolvers_shared_examples.rb b/spec/support/shared_examples/graphql/resolvers/packages_resolvers_shared_examples.rb index aadc061f175..1ea3074b3cb 100644 --- a/spec/support/shared_examples/graphql/resolvers/packages_resolvers_shared_examples.rb +++ b/spec/support/shared_examples/graphql/resolvers/packages_resolvers_shared_examples.rb @@ -52,6 +52,12 @@ RSpec.shared_examples 'group and projects packages resolver' do it { is_expected.to eq([conan_package]) } end + context 'filter by package_version' do + let(:args) { { package_version: '1.0.0', sort: 'CREATED_DESC' } } + + it { is_expected.to eq([conan_package]) } + end + context 'filter by status' do let(:args) { { status: 'error', sort: 'CREATED_DESC' } } |