diff options
Diffstat (limited to 'qa/qa/specs/features/browser_ui/5_package')
17 files changed, 794 insertions, 486 deletions
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb new file mode 100644 index 00000000000..51735d79fbd --- /dev/null +++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Package', :orchestrated, only: { pipeline: :main } do + describe 'Self-managed Container Registry' do + using RSpec::Parameterized::TableSyntax + + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'project-with-registry' + project.template_name = 'express' + project.visibility = :private + end + end + + let(:project_deploy_token) do + Resource::DeployToken.fabricate_via_browser_ui! do |deploy_token| + deploy_token.name = 'registry-deploy-token' + deploy_token.project = project + deploy_token.scopes = [ + :read_repository, + :read_package_registry, + :write_package_registry, + :read_registry, + :write_registry + ] + end + end + + let!(:runner) do + Resource::Runner.fabricate! do |runner| + runner.name = "qa-runner-#{Time.now.to_i}" + runner.tags = ["runner-for-#{project.name}"] + runner.executor = :docker + runner.project = project + end + end + + let(:personal_access_token) { Runtime::Env.personal_access_token } + + before do + Flow::Login.sign_in + project.visit! + end + + after do + runner.remove_via_api! + project.remove_via_api! + end + + where(:authentication_token_type, :token_name) do + :personal_access_token | 'Personal Access Token' + :project_deploy_token | 'Deploy Token' + :ci_job_token | 'Job Token' + end + + with_them do + let(:auth_token) do + case authentication_token_type + when :personal_access_token + "\"#{personal_access_token}\"" + when :project_deploy_token + "\"#{project_deploy_token.password}\"" + when :ci_job_token + '$CI_JOB_TOKEN' + end + end + + let(:auth_user) do + case authentication_token_type + when :personal_access_token + "$CI_REGISTRY_USER" + when :project_deploy_token + "\"#{project_deploy_token.username}\"" + when :ci_job_token + 'gitlab-ci-token' + end + end + + context "when tls is disabled" do + it "using a #{params[:token_name]}, pushes image and deletes tag", :registry do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files([{ + file_path: '.gitlab-ci.yml', + content: + <<~YAML + build: + image: docker:19.03.12 + stage: build + services: + - name: docker:19.03.12-dind + command: ["--insecure-registry=gitlab.test:5050"] + variables: + IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG + script: + - docker login -u #{auth_user} -p #{auth_token} gitlab.test:5050 + - docker build -t $IMAGE_TAG . + - docker push $IMAGE_TAG + tags: + - "runner-for-#{project.name}" + YAML + }]) + end + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('build') + end + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + end + + Page::Project::Menu.perform(&:go_to_container_registry) + + Page::Project::Registry::Show.perform do |registry| + expect(registry).to have_registry_repository(project.path_with_namespace) + + registry.click_on_image(project.path_with_namespace) + expect(registry).to have_tag('master') + + registry.click_delete + expect(registry).not_to have_tag('master') + end + end + end + end + + context "when tls is enabled" do + it "pushes image and deletes tag", :registry_tls, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/2378' do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files([{ + file_path: '.gitlab-ci.yml', + content: + <<~YAML + build: + image: docker:19.03.12 + stage: build + services: + - name: docker:19.03.12-dind + command: + - /bin/sh + - -c + - | + apk add --no-cache openssl + true | openssl s_client -showcerts -connect gitlab.test:5050 > /usr/local/share/ca-certificates/gitlab.test.crt + update-ca-certificates + dockerd-entrypoint.sh || exit + variables: + IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG + script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD gitlab.test:5050 + - docker build -t $IMAGE_TAG . + - docker push $IMAGE_TAG + tags: + - "runner-for-#{project.name}" + YAML + }]) + end + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('build') + end + + Support::Retrier.retry_until(max_duration: 800, sleep_interval: 10) do + project.pipelines.last[:status] == 'success' + end + + Page::Project::Menu.perform(&:go_to_container_registry) + + Page::Project::Registry::Show.perform do |registry| + expect(registry).to have_registry_repository(project.path_with_namespace) + + registry.click_on_image(project.path_with_namespace) + expect(registry).to have_tag('master') + + registry.click_delete + expect(registry).not_to have_tag('master') + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb index 65519cdebec..65519cdebec 100644 --- a/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb diff --git a/qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb index 3ec76e8afad..82b7af8eba7 100644 --- a/qa/qa/specs/features/browser_ui/5_package/online_garbage_collection_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb @@ -2,7 +2,8 @@ module QA RSpec.describe 'Package' do - describe 'Container Registry Online Garbage Collection', :registry_gc, only: { subdomain: %i[pre] } do + # TODO: Remove :requires_admin when the `Runtime::Feature.enable` method call is removed + describe 'Container Registry Online Garbage Collection', :registry_gc, :requires_admin, only: { subdomain: %i[pre] } do let(:group) { Resource::Group.fabricate_via_api! } let(:imported_project) do @@ -23,12 +24,12 @@ module QA STAGE_THREE_VALIDATION_DELAY: "6m" STAGE_FOUR_VALIDATION_DELAY: "12m" STAGE_FIVE_VALIDATION_DELAY: "12m" - + stages: - generate - build - test - + .base: &base image: docker:19 services: @@ -39,11 +40,11 @@ module QA DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" before_script: - - until docker info; do sleep 1; done + - until docker info; do sleep 1; done - mkdir -p $GOPATH - mkdir -p $BUILD_CACHE - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - + test: stage: generate extends: .base @@ -64,6 +65,8 @@ module QA end before do + Runtime::Feature.enable(:paginatable_namespace_drop_down_for_project_creation) + Flow::Login.sign_in imported_project diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb deleted file mode 100644 index 3d02c2884a2..00000000000 --- a/qa/qa/specs/features/browser_ui/5_package/container_registry_omnibus_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Package', :registry, :orchestrated, only: { pipeline: :main } do - describe 'Self-managed Container Registry' do - let(:project) do - Resource::Project.fabricate_via_api! do |project| - project.name = 'project-with-registry' - project.template_name = 'express' - end - end - - let!(:runner) do - Resource::Runner.fabricate! do |runner| - runner.name = "qa-runner-#{Time.now.to_i}" - runner.tags = ["runner-for-#{project.name}"] - runner.executor = :docker - runner.project = project - end - end - - before do - Flow::Login.sign_in - project.visit! - end - - after do - runner.remove_via_api! - end - - it "pushes image and deletes tag", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1911' do - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = project - commit.commit_message = 'Add .gitlab-ci.yml' - commit.add_files([{ - file_path: '.gitlab-ci.yml', - content: - <<~YAML - build: - image: docker:19.03.12 - stage: build - services: - - name: docker:19.03.12-dind - command: - - /bin/sh - - -c - - | - apk add --no-cache openssl - true | openssl s_client -showcerts -connect gitlab.test:5050 > /usr/local/share/ca-certificates/gitlab.test.crt - update-ca-certificates - dockerd-entrypoint.sh || exit - variables: - IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG - script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD gitlab.test:5050 - - docker build -t $IMAGE_TAG . - - docker push $IMAGE_TAG - tags: - - "runner-for-#{project.name}" - YAML - }]) - end - - Flow::Pipeline.visit_latest_pipeline - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('build') - end - - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 800) - end - - Page::Project::Menu.perform(&:go_to_container_registry) - - Page::Project::Registry::Show.perform do |registry| - expect(registry).to have_registry_repository(project.path_with_namespace) - - registry.click_on_image(project.path_with_namespace) - expect(registry).to have_tag('master') - - registry.click_delete - expect(registry).not_to have_tag('master') - end - end - end - end -end diff --git a/qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb b/qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb index ea7f7cc1c05..b941d5434df 100644 --- a/qa/qa/specs/features/browser_ui/5_package/dependency_proxy_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Package', :orchestrated, :registry do + RSpec.describe 'Package', :orchestrated, :registry, only: { pipeline: :main } do describe 'Dependency Proxy' do let(:project) do Resource::Project.fabricate_via_api! do |project| @@ -22,6 +22,7 @@ module QA let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) } let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" } let(:dependency_proxy_url) { "#{gitlab_host_with_port}/#{project.group.full_path}/dependency_proxy/containers" } + let(:image_sha) { 'alpine@sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb' } before do Flow::Login.sign_in @@ -56,22 +57,16 @@ module QA image: "#{docker_client_version}" services: - name: "#{docker_client_version}-dind" - command: - - /bin/sh - - -c - - | - apk add --no-cache openssl - true | openssl s_client -showcerts -connect gitlab.test:5050 > /usr/local/share/ca-certificates/gitlab.test.crt - update-ca-certificates - dockerd-entrypoint.sh || exit + command: ["--insecure-registry=gitlab.test:80"] before_script: - apk add curl jq grep - - docker login -u "$CI_DEPENDENCY_PROXY_USER" -p "$CI_DEPENDENCY_PROXY_PASSWORD" "$CI_DEPENDENCY_PROXY_SERVER" + - echo $CI_DEPENDENCY_PROXY_SERVER + - docker login -u "$CI_DEPENDENCY_PROXY_USER" -p "$CI_DEPENDENCY_PROXY_PASSWORD" gitlab.test:80 script: - - docker pull #{dependency_proxy_url}/alpine:latest + - docker pull #{dependency_proxy_url}/#{image_sha} - TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token) - 'curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1' - - docker pull #{dependency_proxy_url}/alpine:latest + - docker pull #{dependency_proxy_url}/#{image_sha} - 'curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1' tags: - "runner-for-#{project.name}" @@ -95,7 +90,7 @@ module QA Page::Group::Menu.perform(&:go_to_dependency_proxy) Page::Group::DependencyProxy.perform do |index| - expect(index).to have_blob_count("Contains 2 blobs of images") + expect(index).to have_blob_count("Contains 1 blobs of images") end end end diff --git a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb deleted file mode 100644 index bf1d2a04dba..00000000000 --- a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb +++ /dev/null @@ -1,340 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Package', :orchestrated, :packages, :reliable, :object_storage do - describe 'Maven Repository' do - include Runtime::Fixtures - - let(:group_id) { 'com.gitlab.qa' } - let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" } - let(:another_artifact_id) { "maven-#{SecureRandom.hex(8)}" } - let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') } - let(:auth_token) do - unless Page::Main::Menu.perform(&:signed_in?) - Flow::Login.sign_in - end - - Resource::PersonalAccessToken.fabricate!.token - end - - let(:project) do - Resource::Project.fabricate_via_api! do |project| - project.name = 'maven-package-project' - end - end - - let(:another_project) do - Resource::Project.fabricate_via_api! do |another_project| - another_project.name = 'another-maven-package-project' - another_project.group = project.group - end - end - - let(:package) do - Resource::Package.init do |package| - package.name = package_name - package.project = project - end - end - - let!(:runner) do - Resource::Runner.fabricate! do |runner| - runner.name = "qa-runner-#{Time.now.to_i}" - runner.tags = ["runner-for-#{project.group.name}"] - runner.executor = :docker - runner.token = project.group.runners_token - end - end - - let!(:gitlab_address_with_port) do - uri = URI.parse(Runtime::Scenario.gitlab_address) - "#{uri.scheme}://#{uri.host}:#{uri.port}" - end - - let(:pom_xml) do - { - file_path: 'pom.xml', - content: <<~XML - <project> - <groupId>#{group_id}</groupId> - <artifactId>#{artifact_id}</artifactId> - <version>1.0</version> - <modelVersion>4.0.0</modelVersion> - <repositories> - <repository> - <id>#{project.name}</id> - <url>#{gitlab_address_with_port}/api/v4/groups/#{project.group.id}/-/packages/maven</url> - </repository> - </repositories> - <distributionManagement> - <repository> - <id>#{project.name}</id> - <url>#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/maven</url> - </repository> - <snapshotRepository> - <id>#{project.name}</id> - <url>#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/maven</url> - </snapshotRepository> - </distributionManagement> - </project> - XML - } - end - - let(:pom_xml_another_project) do - { - file_path: 'pom.xml', - content: <<~XML - <project> - <groupId>#{group_id}</groupId> - <artifactId>#{another_artifact_id}</artifactId> - <version>1.0</version> - <modelVersion>4.0.0</modelVersion> - <repositories> - <repository> - <id>#{another_project.name}</id> - <url>#{gitlab_address_with_port}/api/v4/groups/#{another_project.group.id}/-/packages/maven</url> - </repository> - </repositories> - <distributionManagement> - <repository> - <id>#{another_project.name}</id> - <url>#{gitlab_address_with_port}/api/v4/projects/#{another_project.id}/packages/maven</url> - </repository> - <snapshotRepository> - <id>#{another_project.name}</id> - <url>#{gitlab_address_with_port}/api/v4/projects/#{another_project.id}/packages/maven</url> - </snapshotRepository> - </distributionManagement> - <dependencies> - <dependency> - <groupId>#{group_id}</groupId> - <artifactId>#{artifact_id}</artifactId> - <version>1.0</version> - </dependency> - </dependencies> - </project> - XML - } - end - - let(:settings_xml) do - { - file_path: 'settings.xml', - content: <<~XML - <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"> - <servers> - <server> - <id>#{project.name}</id> - <configuration> - <httpHeaders> - <property> - <name>Private-Token</name> - <value>#{auth_token}</value> - </property> - </httpHeaders> - </configuration> - </server> - </servers> - </settings> - XML - } - end - - let(:gitlab_ci_deploy_yml) do - { - file_path: '.gitlab-ci.yml', - content: - <<~YAML - deploy: - image: maven:3.6-jdk-11 - script: - - 'mvn deploy -s settings.xml' - - "mvn dependency:get -Dartifact=#{group_id}:#{artifact_id}:1.0" - only: - - "#{project.default_branch}" - tags: - - "runner-for-#{project.group.name}" - YAML - } - end - - let(:gitlab_ci_install_yml) do - { - file_path: '.gitlab-ci.yml', - content: - <<~YAML - install: - image: maven:3.6-jdk-11 - script: - - "mvn install" - only: - - "#{project.default_branch}" - tags: - - "runner-for-#{another_project.group.name}" - YAML - } - end - - after do - runner.remove_via_api! - project.remove_via_api! - another_project.remove_via_api! - end - - it 'pushes and pulls a Maven package via CI and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1627' do - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = project - commit.commit_message = 'Add .gitlab-ci.yml' - commit.add_files([ - gitlab_ci_deploy_yml, - settings_xml, - pom_xml - ]) - end - - project.visit! - Flow::Pipeline.visit_latest_pipeline - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('deploy') - end - - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 800) - end - - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = another_project - commit.commit_message = 'Add .gitlab-ci.yml' - commit.add_files([ - gitlab_ci_install_yml, - pom_xml_another_project - ]) - end - - another_project.visit! - Flow::Pipeline.visit_latest_pipeline - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('install') - end - - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 800) - end - - project.visit! - - Page::Project::Menu.perform(&:click_packages_link) - - Page::Project::Packages::Index.perform do |index| - expect(index).to have_package(package_name) - - index.click_package(package_name) - end - - Page::Project::Packages::Show.perform do |show| - expect(show).to have_package_info(package_name, "1.0") - show.click_delete - end - - Page::Project::Packages::Index.perform do |index| - expect(index).to have_content("Package deleted successfully") - expect(index).not_to have_package(package_name) - end - end - - context 'when "allow duplicate" setting is disabled' do - before do - Flow::Login.sign_in - - project.group.visit! - - Page::Group::Menu.perform(&:go_to_package_settings) - Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled) - end - - it 'prevents users from publishing duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1830' do - with_fixtures([pom_xml, settings_xml]) do |dir| - Service::DockerRun::Maven.new(dir).publish! - end - - project.visit! - Page::Project::Menu.perform(&:click_packages_link) - - Page::Project::Packages::Index.perform do |index| - expect(index).to have_package(package_name) - end - - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = another_project - commit.commit_message = 'Add .gitlab-ci.yml' - commit.add_files([ - gitlab_ci_deploy_yml, - settings_xml, - pom_xml - ]) - end - - another_project.visit! - Flow::Pipeline.visit_latest_pipeline - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('deploy') - end - - Page::Project::Job::Show.perform do |job| - expect(job).not_to be_successful(timeout: 800) - end - end - end - - context 'when "allow duplicate" setting is enabled' do - before do - Flow::Login.sign_in - - project.group.visit! - - Page::Group::Menu.perform(&:go_to_package_settings) - Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled) - end - - it 'allows users to publish duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1829' do - with_fixtures([pom_xml, settings_xml]) do |dir| - Service::DockerRun::Maven.new(dir).publish! - end - - project.visit! - Page::Project::Menu.perform(&:click_packages_link) - - Page::Project::Packages::Index.perform do |index| - expect(index).to have_package(package_name) - end - - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = another_project - commit.commit_message = 'Add .gitlab-ci.yml' - commit.add_files([ - gitlab_ci_deploy_yml, - settings_xml, - pom_xml - ]) - end - - another_project.visit! - Flow::Pipeline.visit_latest_pipeline - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('deploy') - end - - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 800) - end - end - end - end - end -end diff --git a/qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb index 9ddf485870d..9ddf485870d 100644 --- a/qa/qa/specs/features/browser_ui/5_package/composer_registry_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb diff --git a/qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb index a8f1fc2a7de..126be22d760 100644 --- a/qa/qa/specs/features/browser_ui/5_package/conan_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb @@ -17,7 +17,7 @@ module QA let(:package) do Resource::Package.init do |package| - package.name = 'conantest' + package.name = "conantest-#{SecureRandom.hex(8)}" package.project = project end end diff --git a/qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb index 2e5fa2c2904..86aca120eed 100644 --- a/qa/qa/specs/features/browser_ui/5_package/generic_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb @@ -11,7 +11,7 @@ module QA let(:package) do Resource::Package.init do |package| - package.name = "my_package" + package.name = "my_package-#{SecureRandom.hex(8)}" package.project = project end end @@ -36,13 +36,13 @@ module QA upload: stage: upload script: - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file file.txt ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/0.0.1/file.txt' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file file.txt ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/#{package.name}/0.0.1/file.txt' tags: - "runner-for-#{project.name}" download: stage: download script: - - 'wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/0.0.1/file.txt -O file_downloaded.txt' + - 'wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/#{package.name}/0.0.1/file.txt -O file_downloaded.txt' tags: - "runner-for-#{project.name}" YAML diff --git a/qa/qa/specs/features/browser_ui/5_package/helm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb index fe52fd03ad8..3f5e8b1a630 100644 --- a/qa/qa/specs/features/browser_ui/5_package/helm_registry_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb @@ -6,7 +6,7 @@ module QA include Runtime::Fixtures include_context 'packages registry qa scenario' - let(:package_name) { 'gitlab_qa_helm' } + let(:package_name) { "gitlab_qa_helm-#{SecureRandom.hex(8)}" } let(:package_version) { '1.3.7' } let(:package_type) { 'helm' } diff --git a/qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb index ec9feca84b9..2aa93de0b9e 100644 --- a/qa/qa/specs/features/browser_ui/5_package/maven_gradle_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb @@ -8,7 +8,7 @@ module QA include_context 'packages registry qa scenario' let(:group_id) { 'com.gitlab.qa' } - let(:artifact_id) { 'maven_gradle' } + let(:artifact_id) { "maven_gradle-#{SecureRandom.hex(8)}" } let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') } let(:package_version) { '1.3.7' } let(:package_type) { 'maven_gradle' } diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb new file mode 100644 index 00000000000..f42093bffcd --- /dev/null +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb @@ -0,0 +1,317 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Package', :orchestrated, :packages, :object_storage do + describe 'Maven Repository' do + using RSpec::Parameterized::TableSyntax + include Runtime::Fixtures + include_context 'packages registry qa scenario' + + let(:group_id) { 'com.gitlab.qa' } + let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" } + let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') } + let(:package_version) { '1.3.7' } + let(:package_type) { 'maven' } + + let(:package_gitlab_ci_file) do + { + file_path: '.gitlab-ci.yml', + content: + <<~YAML + deploy: + image: maven:3.6-jdk-11 + script: + - 'mvn deploy -s settings.xml' + only: + - "#{package_project.default_branch}" + tags: + - "runner-for-#{package_project.group.name}" + YAML + } + end + + let(:package_pom_file) do + { + file_path: 'pom.xml', + content: <<~XML + <project> + <groupId>#{group_id}</groupId> + <artifactId>#{artifact_id}</artifactId> + <version>#{package_version}</version> + <modelVersion>4.0.0</modelVersion> + <repositories> + <repository> + <id>#{package_project.name}</id> + <url>#{gitlab_address_with_port}/api/v4/groups/#{package_project.group.id}/-/packages/maven</url> + </repository> + </repositories> + <distributionManagement> + <repository> + <id>#{package_project.name}</id> + <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/packages/maven</url> + </repository> + <snapshotRepository> + <id>#{package_project.name}</id> + <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/packages/maven</url> + </snapshotRepository> + </distributionManagement> + </project> + XML + } + end + + let(:client_gitlab_ci_file) do + { + file_path: '.gitlab-ci.yml', + content: + <<~YAML + install: + image: maven:3.6-jdk-11 + script: + - "mvn install -s settings.xml" + only: + - "#{client_project.default_branch}" + tags: + - "runner-for-#{client_project.group.name}" + YAML + } + end + + let(:client_pom_file) do + { + file_path: 'pom.xml', + content: <<~XML + <project> + <groupId>#{group_id}</groupId> + <artifactId>maven_client</artifactId> + <version>1.0</version> + <modelVersion>4.0.0</modelVersion> + <repositories> + <repository> + <id>#{package_project.name}</id> + <url>#{gitlab_address_with_port}/api/v4/groups/#{package_project.group.id}/-/packages/maven</url> + </repository> + </repositories> + <dependencies> + <dependency> + <groupId>#{group_id}</groupId> + <artifactId>#{artifact_id}</artifactId> + <version>#{package_version}</version> + </dependency> + </dependencies> + </project> + XML + } + end + + let(:settings_xml_with_pat) do + { + file_path: 'settings.xml', + content: <<~XML + <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"> + <servers> + <server> + <id>#{package_project.name}</id> + <configuration> + <httpHeaders> + <property> + <name>Private-Token</name> + <value>#{personal_access_token}</value> + </property> + </httpHeaders> + </configuration> + </server> + </servers> + </settings> + XML + } + end + + where(:authentication_token_type, :maven_header_name) do + :personal_access_token | 'Private-Token' + :ci_job_token | 'Job-Token' + :project_deploy_token | 'Deploy-Token' + end + + with_them do + let(:token) do + case authentication_token_type + when :personal_access_token + personal_access_token + when :ci_job_token + '${env.CI_JOB_TOKEN}' + when :project_deploy_token + project_deploy_token.password + end + end + + let(:settings_xml) do + { + file_path: 'settings.xml', + content: <<~XML + <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"> + <servers> + <server> + <id>#{package_project.name}</id> + <configuration> + <httpHeaders> + <property> + <name>#{maven_header_name}</name> + <value>#{token}</value> + </property> + </httpHeaders> + </configuration> + </server> + </servers> + </settings> + XML + } + end + + it "pushes and pulls a maven package via maven using #{params[:authentication_token_type]}" do + # pushing + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = package_project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files([ + package_gitlab_ci_file, + package_pom_file, + settings_xml + ]) + end + + package_project.visit! + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('deploy') + end + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + end + + Page::Project::Menu.perform(&:click_packages_link) + + Page::Project::Packages::Index.perform do |index| + expect(index).to have_package(package_name) + + index.click_package(package_name) + end + + Page::Project::Packages::Show.perform do |show| + expect(show).to have_package_info(package_name, package_version) + end + + # pulling + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = client_project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files([ + client_gitlab_ci_file, + client_pom_file, + settings_xml + ]) + end + + client_project.visit! + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('install') + end + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + end + end + + context 'duplication setting' do + before do + package_project.group.visit! + + Page::Group::Menu.perform(&:go_to_package_settings) + end + + context 'when disabled' do + before do + Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled) + end + + it "prevents users from publishing group level Maven packages duplicates using #{params[:authentication_token_type]}" do + create_duplicated_package + + push_duplicated_package + + client_project.visit! + + show_latest_deploy_job + + Page::Project::Job::Show.perform do |job| + expect(job).not_to be_successful(timeout: 800) + end + end + end + + context 'when enabled' do + before do + Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled) + end + + it "allows users to publish group level Maven packages duplicates using #{params[:authentication_token_type]}" do + create_duplicated_package + + push_duplicated_package + + show_latest_deploy_job + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + end + end + end + + def create_duplicated_package + with_fixtures([package_pom_file, settings_xml_with_pat]) do |dir| + Service::DockerRun::Maven.new(dir).publish! + end + + package_project.visit! + + Page::Project::Menu.perform(&:click_packages_link) + + Page::Project::Packages::Index.perform do |index| + expect(index).to have_package(package_name) + end + end + + def push_duplicated_package + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = client_project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files([ + package_gitlab_ci_file, + package_pom_file, + settings_xml + ]) + end + end + + def show_latest_deploy_job + client_project.visit! + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('deploy') + end + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb index 5a3b4388f0c..f2b1c1b01a0 100644 --- a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module QA - RSpec.describe 'Package', :orchestrated, :packages, :reliable, :object_storage do - describe 'npm registry' do + RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do + describe 'npm instance level endpoint' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures @@ -19,6 +19,11 @@ module QA Resource::DeployToken.fabricate_via_browser_ui! do |deploy_token| deploy_token.name = 'npm-deploy-token' deploy_token.project = project + deploy_token.scopes = [ + :read_repository, + :read_package_registry, + :write_package_registry + ] end end @@ -28,13 +33,13 @@ module QA let!(:project) do Resource::Project.fabricate_via_api! do |project| - project.name = 'npm-project' + project.name = 'npm-instace-level-publish' end end let!(:another_project) do Resource::Project.fabricate_via_api! do |another_project| - another_project.name = 'npm-another-project' + another_project.name = 'npm-instance-level-install' another_project.template_name = 'express' another_project.group = project.group end @@ -54,7 +59,7 @@ module QA file_path: '.gitlab-ci.yml', content: <<~YAML - image: node:14-buster + image: node:latest stages: - deploy @@ -62,6 +67,7 @@ module QA deploy: stage: deploy script: + - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=#{auth_token}">.npmrc - npm publish only: - "#{project.default_branch}" @@ -119,7 +125,7 @@ module QA let(:package) do Resource::Package.init do |package| - package.name = "@#{registry_scope}/#{project.name}" + package.name = "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}" package.project = project end end @@ -149,23 +155,12 @@ module QA end end - let(:npmrc) do - { - file_path: '.npmrc', - content: <<~NPMRC - //#{gitlab_host_with_port}/api/v4/projects/#{project.id}/packages/npm/:_authToken=#{auth_token} - @#{registry_scope}:registry=#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/npm/ - NPMRC - } - end - - it "push and pull a npm package via CI using a #{params[:token_name]}", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1772' do + it "push and pull a npm package via CI using a #{params[:token_name]}" do Resource::Repository::Commit.fabricate_via_api! do |commit| commit.project = project commit.commit_message = 'Add .gitlab-ci.yml' commit.add_files([ gitlab_ci_deploy_yaml, - npmrc, package_json ]) end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb new file mode 100644 index 00000000000..832f8c7f72c --- /dev/null +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb @@ -0,0 +1,197 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do + describe 'npm project level endpoint' do + using RSpec::Parameterized::TableSyntax + include Runtime::Fixtures + + let!(:registry_scope) { Runtime::Namespace.sandbox_name } + let!(:personal_access_token) do + unless Page::Main::Menu.perform(&:signed_in?) + Flow::Login.sign_in + end + + Resource::PersonalAccessToken.fabricate!.token + end + + let(:project_deploy_token) do + Resource::DeployToken.fabricate_via_browser_ui! do |deploy_token| + deploy_token.name = 'npm-deploy-token' + deploy_token.project = project + deploy_token.scopes = [ + :read_repository, + :read_package_registry, + :write_package_registry + ] + end + end + + let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) } + let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" } + let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" } + + let!(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'npm-project-level' + end + end + + let!(:runner) do + Resource::Runner.fabricate! do |runner| + runner.name = "qa-runner-#{Time.now.to_i}" + runner.tags = ["runner-for-#{project.name}"] + runner.executor = :docker + runner.project = project + end + end + + let(:gitlab_ci_yaml) do + { + file_path: '.gitlab-ci.yml', + content: + <<~YAML + image: node:latest + + stages: + - deploy + - install + + deploy: + stage: deploy + script: + - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=#{auth_token}">.npmrc + - npm publish + only: + - "#{project.default_branch}" + tags: + - "runner-for-#{project.name}" + install: + stage: install + script: + - "npm config set @#{registry_scope}:registry #{gitlab_address_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/" + - "npm install #{package.name}" + cache: + key: ${CI_BUILD_REF_NAME} + paths: + - node_modules/ + artifacts: + paths: + - node_modules/ + only: + - "#{project.default_branch}" + tags: + - "runner-for-#{project.name}" + YAML + } + end + + let(:package_json) do + { + file_path: 'package.json', + content: <<~JSON + { + "name": "@#{registry_scope}/mypackage", + "version": "1.0.0", + "description": "Example package for GitLab npm registry", + "publishConfig": { + "@#{registry_scope}:registry": "#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/npm/" + } + } + JSON + } + end + + let(:package) do + Resource::Package.init do |package| + package.name = "@#{registry_scope}/mypackage-#{SecureRandom.hex(8)}" + package.project = project + end + end + + after do + package.remove_via_api! + runner.remove_via_api! + project.remove_via_api! + end + + where(:authentication_token_type, :token_name) do + :personal_access_token | 'Personal Access Token' + :ci_job_token | 'CI Job Token' + :project_deploy_token | 'Deploy Token' + end + + with_them do + let(:auth_token) do + case authentication_token_type + when :personal_access_token + "\"#{personal_access_token}\"" + when :ci_job_token + '${CI_JOB_TOKEN}' + when :project_deploy_token + "\"#{project_deploy_token.password}\"" + end + end + + it "push and pull a npm package via CI using a #{params[:token_name]}", quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/344537', type: :investigating } do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files([ + gitlab_ci_yaml, + package_json + ]) + end + + project.visit! + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('deploy') + end + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + end + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('install') + end + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + job.click_browse_button + end + + Page::Project::Artifact::Show.perform do |artifacts| + artifacts.go_to_directory('node_modules') + artifacts.go_to_directory("@#{registry_scope}") + expect(artifacts).to have_content("mypackage") + end + + project.visit! + Page::Project::Menu.perform(&:click_packages_link) + + Page::Project::Packages::Index.perform do |index| + expect(index).to have_package(package.name) + + index.click_package(package.name) + end + + Page::Project::Packages::Show.perform do |show| + expect(show).to have_package_info(package.name, "1.0.0") + + show.click_delete + end + + Page::Project::Packages::Index.perform do |index| + expect(index).to have_content("Package deleted successfully") + expect(index).not_to have_package(package.name) + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget_repository_spec.rb index 8a6752ed817..0b4825715c1 100644 --- a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget_repository_spec.rb @@ -85,7 +85,7 @@ module QA end end - it "publishes a nuget package at the project level, installs and deletes it at the group level using a #{params[:token_name]}", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1073' do + it "publishes a nuget package at the project level, installs and deletes it at the group level using a #{params[:token_name]}" do Flow::Login.sign_in Resource::Repository::Commit.fabricate_via_api! do |commit| diff --git a/qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb index dfc9202ebed..e727a89a584 100644 --- a/qa/qa/specs/features/browser_ui/5_package/pypi_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb @@ -12,7 +12,7 @@ module QA let(:package) do Resource::Package.init do |package| - package.name = 'mypypipackage' + package.name = "mypypipackage-#{SecureRandom.hex(8)}" package.project = project end end @@ -57,7 +57,7 @@ module QA install: stage: install script: - - "pip install mypypipackage --no-deps --index-url #{uri.scheme}://#{personal_access_token}:#{personal_access_token}@#{gitlab_host_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple --trusted-host #{gitlab_host_with_port}" + - "pip install #{package.name} --no-deps --index-url #{uri.scheme}://#{personal_access_token}:#{personal_access_token}@#{gitlab_host_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple --trusted-host #{gitlab_host_with_port}" tags: - "runner-for-#{project.name}" @@ -70,7 +70,7 @@ module QA import setuptools setuptools.setup( - name="mypypipackage", + name="#{package.name}", version="0.0.1", author="Example Author", author_email="author@example.com", diff --git a/qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb index 9a45b072eed..ecf14a25b8d 100644 --- a/qa/qa/specs/features/browser_ui/5_package/rubygems_registry_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb @@ -13,7 +13,7 @@ module QA let(:package) do Resource::Package.init do |package| - package.name = 'mygem' + package.name = "mygem-#{SecureRandom.hex(8)}" package.project = project end end @@ -46,17 +46,9 @@ module QA it 'publishes and deletes a Ruby gem', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1906' do Flow::Login.sign_in - Resource::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.directory = Pathname - .new(__dir__) - .join('../../../../fixtures/rubygems_package') - push.commit_message = 'RubyGems package' - end - Resource::Repository::Commit.fabricate_via_api! do |commit| commit.project = project - commit.commit_message = 'Add mygem.gemspec' + commit.commit_message = 'Add package files' commit.add_files( [ { @@ -74,8 +66,8 @@ module QA echo "#{gitlab_address_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/rubygems: '${CI_JOB_TOKEN}'" >> ~/.gem/credentials - chmod 0600 ~/.gem/credentials script: - - gem build mygem - - gem push mygem-0.0.1.gem --host #{gitlab_address_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/rubygems + - gem build #{package.name} + - gem push #{package.name}-0.0.1.gem --host #{gitlab_address_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/rubygems tags: - "runner-for-#{project.name}" YAML @@ -90,6 +82,52 @@ module QA end end RUBY + }, + { + file_path: "#{package.name}.gemspec", + content: + <<~RUBY + # frozen_string_literal: true + + Gem::Specification.new do |s| + s.name = '#{package.name}' + s.authors = ['Tanuki Steve', 'Hal 9000'] + s.author = 'Tanuki Steve' + s.version = '0.0.1' + s.date = '2011-09-29' + s.summary = 'this is a test package' + s.files = ['lib/hello_gem.rb'] + s.require_paths = ['lib'] + + s.description = 'A test package for GitLab.' + s.email = 'tanuki@not_real.com' + s.homepage = 'https://gitlab.com/ruby-co/my-package' + s.license = 'MIT' + + s.metadata = { + 'bug_tracker_uri' => 'https://gitlab.com/ruby-co/my-package/issues', + 'changelog_uri' => 'https://gitlab.com/ruby-co/my-package/CHANGELOG.md', + 'documentation_uri' => 'https://gitlab.com/ruby-co/my-package/docs', + 'mailing_list_uri' => 'https://gitlab.com/ruby-co/my-package/mailme', + 'source_code_uri' => 'https://gitlab.com/ruby-co/my-package' + } + + s.bindir = 'bin' + s.platform = Gem::Platform::RUBY + s.post_install_message = 'Installed, thank you!' + s.rdoc_options = ['--main'] + s.required_ruby_version = '>= 2.7.0' + s.required_rubygems_version = '>= 1.8.11' + s.requirements = 'A high powered server or calculator' + s.rubygems_version = '1.8.09' + + s.add_dependency 'dependency_1', '~> 1.2.3' + s.add_dependency 'dependency_2', '3.0.0' + s.add_dependency 'dependency_3', '>= 1.0.0' + s.add_dependency 'dependency_4' + end + + RUBY } ] ) |