1# frozen_string_literal: true 2 3module QA 4 RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do 5 describe 'npm instance level endpoint' do 6 using RSpec::Parameterized::TableSyntax 7 include Runtime::Fixtures 8 9 let!(:registry_scope) { Runtime::Namespace.sandbox_name } 10 let!(:personal_access_token) do 11 unless Page::Main::Menu.perform(&:signed_in?) 12 Flow::Login.sign_in 13 end 14 15 Resource::PersonalAccessToken.fabricate!.token 16 end 17 18 let(:project_deploy_token) do 19 Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token| 20 deploy_token.name = 'npm-deploy-token' 21 deploy_token.project = project 22 deploy_token.scopes = %w[ 23 read_repository 24 read_package_registry 25 write_package_registry 26 ] 27 end 28 end 29 30 let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) } 31 let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" } 32 let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" } 33 34 let!(:project) do 35 Resource::Project.fabricate_via_api! do |project| 36 project.name = 'npm-instace-level-publish' 37 end 38 end 39 40 let!(:another_project) do 41 Resource::Project.fabricate_via_api! do |another_project| 42 another_project.name = 'npm-instance-level-install' 43 another_project.template_name = 'express' 44 another_project.group = project.group 45 end 46 end 47 48 let!(:runner) do 49 Resource::Runner.fabricate! do |runner| 50 runner.name = "qa-runner-#{Time.now.to_i}" 51 runner.tags = ["runner-for-#{project.group.name}"] 52 runner.executor = :docker 53 runner.token = project.group.runners_token 54 end 55 end 56 57 let(:gitlab_ci_deploy_yaml) do 58 { 59 file_path: '.gitlab-ci.yml', 60 content: 61 <<~YAML 62 image: node:latest 63 64 stages: 65 - deploy 66 67 deploy: 68 stage: deploy 69 script: 70 - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=#{auth_token}">.npmrc 71 - npm publish 72 only: 73 - "#{project.default_branch}" 74 tags: 75 - "runner-for-#{project.group.name}" 76 YAML 77 } 78 end 79 80 let(:gitlab_ci_install_yaml) do 81 { 82 file_path: '.gitlab-ci.yml', 83 content: 84 <<~YAML 85 image: node:latest 86 87 stages: 88 - install 89 90 install: 91 stage: install 92 script: 93 - "npm config set @#{registry_scope}:registry #{gitlab_address_with_port}/api/v4/packages/npm/" 94 - "npm install #{package.name}" 95 cache: 96 key: ${CI_BUILD_REF_NAME} 97 paths: 98 - node_modules/ 99 artifacts: 100 paths: 101 - node_modules/ 102 only: 103 - "#{another_project.default_branch}" 104 tags: 105 - "runner-for-#{another_project.group.name}" 106 YAML 107 } 108 end 109 110 let(:package_json) do 111 { 112 file_path: 'package.json', 113 content: <<~JSON 114 { 115 "name": "#{package.name}", 116 "version": "1.0.0", 117 "description": "Example package for GitLab npm registry", 118 "publishConfig": { 119 "@#{registry_scope}:registry": "#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/npm/" 120 } 121 } 122 JSON 123 } 124 end 125 126 let(:package) do 127 Resource::Package.init do |package| 128 package.name = "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}" 129 package.project = project 130 end 131 end 132 133 after do 134 package.remove_via_api! 135 runner.remove_via_api! 136 project.remove_via_api! 137 another_project.remove_via_api! 138 end 139 140 where(:authentication_token_type, :token_name) do 141 :personal_access_token | 'Personal Access Token' 142 :ci_job_token | 'CI Job Token' 143 :project_deploy_token | 'Deploy Token' 144 end 145 146 with_them do 147 let(:auth_token) do 148 case authentication_token_type 149 when :personal_access_token 150 "\"#{personal_access_token}\"" 151 when :ci_job_token 152 '${CI_JOB_TOKEN}' 153 when :project_deploy_token 154 "\"#{project_deploy_token.token}\"" 155 end 156 end 157 158 it "push and pull a npm package via CI using a #{params[:token_name]}" do 159 Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do 160 Resource::Repository::Commit.fabricate_via_api! do |commit| 161 commit.project = project 162 commit.commit_message = 'Add .gitlab-ci.yml' 163 commit.add_files([ 164 gitlab_ci_deploy_yaml, 165 package_json 166 ]) 167 end 168 end 169 170 project.visit! 171 Flow::Pipeline.visit_latest_pipeline 172 173 Page::Project::Pipeline::Show.perform do |pipeline| 174 pipeline.click_job('deploy') 175 end 176 177 Page::Project::Job::Show.perform do |job| 178 expect(job).to be_successful(timeout: 800) 179 end 180 181 Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do 182 Resource::Repository::Commit.fabricate_via_api! do |commit| 183 commit.project = another_project 184 commit.commit_message = 'Add .gitlab-ci.yml' 185 commit.add_files([ 186 gitlab_ci_install_yaml 187 ]) 188 end 189 end 190 191 another_project.visit! 192 Flow::Pipeline.visit_latest_pipeline 193 194 Page::Project::Pipeline::Show.perform do |pipeline| 195 pipeline.click_job('install') 196 end 197 198 Page::Project::Job::Show.perform do |job| 199 expect(job).to be_successful(timeout: 800) 200 job.click_browse_button 201 end 202 203 Page::Project::Artifact::Show.perform do |artifacts| 204 artifacts.go_to_directory('node_modules') 205 artifacts.go_to_directory("@#{registry_scope}") 206 expect(artifacts).to have_content("#{project.name}") 207 end 208 209 project.visit! 210 Page::Project::Menu.perform(&:click_packages_link) 211 212 Page::Project::Packages::Index.perform do |index| 213 expect(index).to have_package(package.name) 214 215 index.click_package(package.name) 216 end 217 218 Page::Project::Packages::Show.perform do |show| 219 expect(show).to have_package_info(package.name, "1.0.0") 220 221 show.click_delete 222 end 223 224 Page::Project::Packages::Index.perform do |index| 225 expect(index).to have_content("Package deleted successfully") 226 expect(index).not_to have_package(package.name) 227 end 228 end 229 end 230 end 231 end 232end 233