Commit 39e034d0 authored by Steve Abrams's avatar Steve Abrams Committed by Kerri Miller

Add build info to all package types

Update Conan, PyPI, Composer, and NuGet
to save build_infos and package_file_build_infos.

Refactor the saving of these objects to be in a
common set of services.
parent 2f6b9388
...@@ -16,6 +16,8 @@ module Packages ...@@ -16,6 +16,8 @@ module Packages
composer_json: composer_json composer_json: composer_json
}) })
end end
created_package
end end
private private
......
...@@ -12,7 +12,7 @@ module Packages ...@@ -12,7 +12,7 @@ module Packages
end end
def execute def execute
package.package_files.create!( package_file = package.package_files.build(
file: file, file: file,
size: params['file.size'], size: params['file.size'],
file_name: params[:file_name], file_name: params[:file_name],
...@@ -25,6 +25,13 @@ module Packages ...@@ -25,6 +25,13 @@ module Packages
conan_file_type: params[:conan_file_type] conan_file_type: params[:conan_file_type]
} }
) )
if params[:build].present?
package_file.package_file_build_infos << package_file.package_file_build_infos.build(pipeline: params[:build].pipeline)
end
package_file.save!
package_file
end end
end end
end end
......
...@@ -8,9 +8,9 @@ module Packages ...@@ -8,9 +8,9 @@ module Packages
project project
.packages .packages
.with_package_type(package_type) .with_package_type(package_type)
.safe_find_or_create_by!(name: name, version: version) do |pkg| .safe_find_or_create_by!(name: name, version: version) do |package|
pkg.creator = package_creator package.creator = package_creator
yield pkg if block_given? add_build_info(package)
end end
end end
...@@ -18,7 +18,9 @@ module Packages ...@@ -18,7 +18,9 @@ module Packages
project project
.packages .packages
.with_package_type(package_type) .with_package_type(package_type)
.create!(package_attrs(attrs)) .create!(package_attrs(attrs)) do |package|
add_build_info(package)
end
end end
private private
...@@ -34,5 +36,11 @@ module Packages ...@@ -34,5 +36,11 @@ module Packages
def package_creator def package_creator
current_user if current_user.is_a?(User) current_user if current_user.is_a?(User)
end end
def add_build_info(package)
if params[:build].present?
package.build_infos.new(pipeline: params[:build].pipeline)
end
end
end end
end end
...@@ -18,9 +18,12 @@ module Packages ...@@ -18,9 +18,12 @@ module Packages
build: params[:build] build: params[:build]
} }
::Packages::Generic::FindOrCreatePackageService package = ::Packages::Generic::FindOrCreatePackageService
.new(project, current_user, package_params) .new(project, current_user, package_params)
.execute .execute
package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present?
package
end end
def create_package_file(package) def create_package_file(package)
......
...@@ -4,11 +4,7 @@ module Packages ...@@ -4,11 +4,7 @@ module Packages
module Generic module Generic
class FindOrCreatePackageService < ::Packages::CreatePackageService class FindOrCreatePackageService < ::Packages::CreatePackageService
def execute def execute
find_or_create_package!(::Packages::Package.package_types['generic']) do |package| find_or_create_package!(::Packages::Package.package_types['generic'])
if params[:build].present?
package.build_infos.new(pipeline: params[:build].pipeline)
end
end
end end
end end
end end
......
...@@ -46,7 +46,7 @@ module Packages ...@@ -46,7 +46,7 @@ module Packages
.execute .execute
end end
package.build_infos.create!(pipeline: params[:build].pipeline) if params[:build].present? package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present?
package package
end end
......
...@@ -17,10 +17,6 @@ module Packages ...@@ -17,10 +17,6 @@ module Packages
def create_npm_package! def create_npm_package!
package = create_package!(:npm, name: name, version: version) package = create_package!(:npm, name: name, version: version)
if build.present?
package.build_infos.create!(pipeline: build.pipeline)
end
::Packages::CreatePackageFileService.new(package, file_params).execute ::Packages::CreatePackageFileService.new(package, file_params).execute
::Packages::CreateDependencyService.new(package, package_dependencies).execute ::Packages::CreateDependencyService.new(package, package_dependencies).execute
::Packages::Npm::CreateTagService.new(package, dist_tag).execute ::Packages::Npm::CreateTagService.new(package, dist_tag).execute
...@@ -50,10 +46,6 @@ module Packages ...@@ -50,10 +46,6 @@ module Packages
params[:versions][version] params[:versions][version]
end end
def build
params[:build]
end
def dist_tag def dist_tag
params['dist-tags'].each_key.first params['dist-tags'].each_key.first
end end
......
...@@ -19,6 +19,8 @@ module Packages ...@@ -19,6 +19,8 @@ module Packages
Packages::Pypi::Metadatum.upsert(meta.attributes) Packages::Pypi::Metadatum.upsert(meta.attributes)
::Packages::CreatePackageFileService.new(created_package, file_params).execute ::Packages::CreatePackageFileService.new(created_package, file_params).execute
created_package
end end
end end
...@@ -32,6 +34,7 @@ module Packages ...@@ -32,6 +34,7 @@ module Packages
def file_params def file_params
{ {
build: params[:build],
file: params[:content], file: params[:content],
file_name: params[:content].original_filename, file_name: params[:content].original_filename,
file_md5: params[:md5_digest], file_md5: params[:md5_digest],
......
---
title: Create package build_info records for Conan, NuGet, PyPI, and Composer packages
and package files
merge_request: 48811
author:
type: added
...@@ -132,7 +132,7 @@ module API ...@@ -132,7 +132,7 @@ module API
track_package_event('push_package', :composer) track_package_event('push_package', :composer)
::Packages::Composer::CreatePackageService ::Packages::Composer::CreatePackageService
.new(authorized_user_project, current_user, declared_params) .new(authorized_user_project, current_user, declared_params.merge(build: current_authenticated_job))
.execute .execute
created! created!
......
...@@ -164,7 +164,11 @@ module API ...@@ -164,7 +164,11 @@ module API
end end
def find_or_create_package def find_or_create_package
package || ::Packages::Conan::CreatePackageService.new(project, current_user, params).execute package || ::Packages::Conan::CreatePackageService.new(
project,
current_user,
params.merge(build: current_authenticated_job)
).execute
end end
def track_push_package_event def track_push_package_event
...@@ -184,7 +188,11 @@ module API ...@@ -184,7 +188,11 @@ module API
def create_package_file_with_type(file_type, current_package) def create_package_file_with_type(file_type, current_package)
unless params[:file].size == 0 # rubocop: disable Style/ZeroLengthPredicate unless params[:file].size == 0 # rubocop: disable Style/ZeroLengthPredicate
# conan sends two upload requests, the first has no file, so we skip record creation if file.size == 0 # conan sends two upload requests, the first has no file, so we skip record creation if file.size == 0
::Packages::Conan::CreatePackageFileService.new(current_package, params[:file], params.merge(conan_file_type: file_type)).execute ::Packages::Conan::CreatePackageFileService.new(
current_package,
params[:file],
params.merge(conan_file_type: file_type, build: current_authenticated_job)
).execute
end end
end end
......
...@@ -101,11 +101,16 @@ module API ...@@ -101,11 +101,16 @@ module API
file_name: PACKAGE_FILENAME file_name: PACKAGE_FILENAME
) )
package = ::Packages::Nuget::CreatePackageService.new(authorized_user_project, current_user) package = ::Packages::Nuget::CreatePackageService.new(
.execute authorized_user_project,
current_user,
package_file = ::Packages::CreatePackageFileService.new(package, file_params) declared_params.merge(build: current_authenticated_job)
.execute ).execute
package_file = ::Packages::CreatePackageFileService.new(
package,
file_params.merge(build: current_authenticated_job)
).execute
track_package_event('push_package', :nuget) track_package_event('push_package', :nuget)
......
...@@ -127,7 +127,7 @@ module API ...@@ -127,7 +127,7 @@ module API
track_package_event('push_package', :pypi) track_package_event('push_package', :pypi)
::Packages::Pypi::CreatePackageService ::Packages::Pypi::CreatePackageService
.new(authorized_user_project, current_user, declared_params) .new(authorized_user_project, current_user, declared_params.merge(build: current_authenticated_job))
.execute .execute
created! created!
......
...@@ -41,6 +41,8 @@ RSpec.describe Packages::Composer::CreatePackageService do ...@@ -41,6 +41,8 @@ RSpec.describe Packages::Composer::CreatePackageService do
it_behaves_like 'assigns the package creator' do it_behaves_like 'assigns the package creator' do
let(:package) { created_package } let(:package) { created_package }
end end
it_behaves_like 'assigns build to package'
end end
context 'with a tag' do context 'with a tag' do
...@@ -62,6 +64,8 @@ RSpec.describe Packages::Composer::CreatePackageService do ...@@ -62,6 +64,8 @@ RSpec.describe Packages::Composer::CreatePackageService do
it_behaves_like 'assigns the package creator' do it_behaves_like 'assigns the package creator' do
let(:package) { created_package } let(:package) { created_package }
end end
it_behaves_like 'assigns build to package'
end end
end end
......
...@@ -5,11 +5,12 @@ RSpec.describe Packages::Conan::CreatePackageFileService do ...@@ -5,11 +5,12 @@ RSpec.describe Packages::Conan::CreatePackageFileService do
include WorkhorseHelpers include WorkhorseHelpers
let_it_be(:package) { create(:conan_package) } let_it_be(:package) { create(:conan_package) }
let_it_be(:user) { create(:user) }
describe '#execute' do describe '#execute' do
let(:file_name) { 'foo.tgz' } let(:file_name) { 'foo.tgz' }
subject { described_class.new(package, file, params) } subject { described_class.new(package, file, params).execute }
shared_examples 'a valid package_file' do shared_examples 'a valid package_file' do
let(:params) do let(:params) do
...@@ -27,7 +28,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do ...@@ -27,7 +28,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do
end end
it 'creates a new package file' do it 'creates a new package file' do
package_file = subject.execute package_file = subject
expect(package_file).to be_valid expect(package_file).to be_valid
expect(package_file.file_name).to eq(file_name) expect(package_file.file_name).to eq(file_name)
...@@ -40,6 +41,8 @@ RSpec.describe Packages::Conan::CreatePackageFileService do ...@@ -40,6 +41,8 @@ RSpec.describe Packages::Conan::CreatePackageFileService do
expect(package_file.conan_file_metadatum.conan_file_type).to eq('package_file') expect(package_file.conan_file_metadatum.conan_file_type).to eq('package_file')
expect(package_file.file.read).to eq('content') expect(package_file.file.read).to eq('content')
end end
it_behaves_like 'assigns build to package file'
end end
shared_examples 'a valid recipe_file' do shared_examples 'a valid recipe_file' do
...@@ -56,7 +59,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do ...@@ -56,7 +59,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do
end end
it 'creates a new recipe file' do it 'creates a new recipe file' do
package_file = subject.execute package_file = subject
expect(package_file).to be_valid expect(package_file).to be_valid
expect(package_file.file_name).to eq(file_name) expect(package_file.file_name).to eq(file_name)
...@@ -69,6 +72,8 @@ RSpec.describe Packages::Conan::CreatePackageFileService do ...@@ -69,6 +72,8 @@ RSpec.describe Packages::Conan::CreatePackageFileService do
expect(package_file.conan_file_metadatum.conan_file_type).to eq('recipe_file') expect(package_file.conan_file_metadatum.conan_file_type).to eq('recipe_file')
expect(package_file.file.read).to eq('content') expect(package_file.file.read).to eq('content')
end end
it_behaves_like 'assigns build to package file'
end end
context 'with temp file' do context 'with temp file' do
...@@ -123,7 +128,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do ...@@ -123,7 +128,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do
end end
it 'raises an error' do it 'raises an error' do
expect { subject.execute }.to raise_error(ActiveRecord::RecordInvalid) expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
end end
end end
end end
......
...@@ -30,6 +30,7 @@ RSpec.describe Packages::Conan::CreatePackageService do ...@@ -30,6 +30,7 @@ RSpec.describe Packages::Conan::CreatePackageService do
end end
it_behaves_like 'assigns the package creator' it_behaves_like 'assigns the package creator'
it_behaves_like 'assigns build to package'
end end
context 'invalid params' do context 'invalid params' do
......
...@@ -4,10 +4,11 @@ require 'spec_helper' ...@@ -4,10 +4,11 @@ require 'spec_helper'
RSpec.describe Packages::CreatePackageFileService do RSpec.describe Packages::CreatePackageFileService do
let_it_be(:package) { create(:maven_package) } let_it_be(:package) { create(:maven_package) }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:service) { described_class.new(package, params) }
subject { described_class.new(package, params) }
describe '#execute' do describe '#execute' do
subject { service.execute }
context 'with valid params' do context 'with valid params' do
let(:params) do let(:params) do
{ {
...@@ -17,11 +18,13 @@ RSpec.describe Packages::CreatePackageFileService do ...@@ -17,11 +18,13 @@ RSpec.describe Packages::CreatePackageFileService do
end end
it 'creates a new package file' do it 'creates a new package file' do
package_file = subject.execute package_file = subject
expect(package_file).to be_valid expect(package_file).to be_valid
expect(package_file.file_name).to eq('foo.jar') expect(package_file.file_name).to eq('foo.jar')
end end
it_behaves_like 'assigns build to package file'
end end
context 'file is missing' do context 'file is missing' do
...@@ -32,17 +35,7 @@ RSpec.describe Packages::CreatePackageFileService do ...@@ -32,17 +35,7 @@ RSpec.describe Packages::CreatePackageFileService do
end end
it 'raises an error' do it 'raises an error' do
expect { subject.execute }.to raise_error(ActiveRecord::RecordInvalid) expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
end
end
context 'with a build' do
let_it_be(:pipeline) { create(:ci_pipeline, user: user) }
let(:build) { double('build', pipeline: pipeline) }
let(:params) { { file: Tempfile.new, file_name: 'foo.jar', build: build } }
it 'creates a build_info' do
expect { subject.execute }.to change { Packages::PackageFileBuildInfo.count }.by(1)
end end
end end
end end
......
...@@ -23,6 +23,8 @@ RSpec.describe Packages::Generic::CreatePackageFileService do ...@@ -23,6 +23,8 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
} }
end end
subject { described_class.new(project, user, params).execute }
before do before do
FileUtils.touch(temp_file) FileUtils.touch(temp_file)
end end
...@@ -41,9 +43,7 @@ RSpec.describe Packages::Generic::CreatePackageFileService do ...@@ -41,9 +43,7 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
expect(::Packages::Generic::FindOrCreatePackageService).to receive(:new).with(project, user, package_params).and_return(package_service) expect(::Packages::Generic::FindOrCreatePackageService).to receive(:new).with(project, user, package_params).and_return(package_service)
expect(package_service).to receive(:execute).and_return(package) expect(package_service).to receive(:execute).and_return(package)
service = described_class.new(project, user, params) expect { subject }.to change { package.package_files.count }.by(1)
expect { service.execute }.to change { package.package_files.count }.by(1)
.and change { Packages::PackageFileBuildInfo.count }.by(1) .and change { Packages::PackageFileBuildInfo.count }.by(1)
package_file = package.package_files.last package_file = package.package_files.last
...@@ -54,5 +54,7 @@ RSpec.describe Packages::Generic::CreatePackageFileService do ...@@ -54,5 +54,7 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
expect(package_file.file_sha256).to eq(sha256) expect(package_file.file_sha256).to eq(sha256)
end end
end end
it_behaves_like 'assigns build to package file'
end end
end end
...@@ -31,5 +31,6 @@ RSpec.describe Packages::Nuget::CreatePackageService do ...@@ -31,5 +31,6 @@ RSpec.describe Packages::Nuget::CreatePackageService do
end end
it_behaves_like 'assigns the package creator' it_behaves_like 'assigns the package creator'
it_behaves_like 'assigns build to package'
end end
end end
...@@ -51,6 +51,8 @@ RSpec.describe Packages::Pypi::CreatePackageService do ...@@ -51,6 +51,8 @@ RSpec.describe Packages::Pypi::CreatePackageService do
let(:package) { created_package } let(:package) { created_package }
end end
it_behaves_like 'assigns build to package'
context 'with an existing package' do context 'with an existing package' do
before do before do
described_class.new(project, user, params).execute described_class.new(project, user, params).execute
......
...@@ -14,6 +14,24 @@ RSpec.shared_examples 'assigns build to package' do ...@@ -14,6 +14,24 @@ RSpec.shared_examples 'assigns build to package' do
end end
end end
RSpec.shared_examples 'assigns build to package file' do
context 'with build info' do
let(:job) { create(:ci_build, user: user) }
let(:params) { super().merge(build: job) }
it 'assigns the pipeline to the package' do
package_file = subject
expect(package_file.package_file_build_infos).to be_present
expect(package_file.pipelines.first).to eq job.pipeline
end
it 'creates a new PackageFileBuildInfo record' do
expect { subject }.to change { Packages::PackageFileBuildInfo.count }.by(1)
end
end
end
RSpec.shared_examples 'assigns the package creator' do RSpec.shared_examples 'assigns the package creator' do
it 'assigns the package creator' do it 'assigns the package creator' do
subject subject
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment