Commit da06714d authored by Giorgenes Gelatti's avatar Giorgenes Gelatti Committed by Jan Provaznik

Saves build info to packages

- Adds Packages::PackageBuildInfo migration
- Assign build info for npm packages
- Save pipeline info to Maven packages
- Add spec to job assign to packages
parent 31e525db
---
title: Add Pipeline Metadata to Packages
merge_request: 19796
author:
type: added
# frozen_string_literal: true
class CreatePackageBuildInfo < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :packages_build_infos do |t|
t.references :package, null: false, foreign_key: { to_table: :packages_packages, on_delete: :cascade }, type: :integer, index: { unique: true }
t.references :pipeline, index: true, null: true, foreign_key: { to_table: :ci_pipelines, on_delete: :nullify }, type: :integer
end
end
end
...@@ -2846,6 +2846,13 @@ ActiveRecord::Schema.define(version: 2019_12_08_071112) do ...@@ -2846,6 +2846,13 @@ ActiveRecord::Schema.define(version: 2019_12_08_071112) do
t.index ["project_id", "token_encrypted"], name: "index_feature_flags_clients_on_project_id_and_token_encrypted", unique: true t.index ["project_id", "token_encrypted"], name: "index_feature_flags_clients_on_project_id_and_token_encrypted", unique: true
end end
create_table "packages_build_infos", force: :cascade do |t|
t.integer "package_id", null: false
t.integer "pipeline_id"
t.index ["package_id"], name: "index_packages_build_infos_on_package_id", unique: true
t.index ["pipeline_id"], name: "index_packages_build_infos_on_pipeline_id"
end
create_table "packages_conan_file_metadata", force: :cascade do |t| create_table "packages_conan_file_metadata", force: :cascade do |t|
t.bigint "package_file_id", null: false t.bigint "package_file_id", null: false
t.datetime_with_timezone "created_at", null: false t.datetime_with_timezone "created_at", null: false
...@@ -4644,6 +4651,8 @@ ActiveRecord::Schema.define(version: 2019_12_08_071112) do ...@@ -4644,6 +4651,8 @@ ActiveRecord::Schema.define(version: 2019_12_08_071112) do
add_foreign_key "operations_feature_flag_scopes", "operations_feature_flags", column: "feature_flag_id", on_delete: :cascade add_foreign_key "operations_feature_flag_scopes", "operations_feature_flags", column: "feature_flag_id", on_delete: :cascade
add_foreign_key "operations_feature_flags", "projects", on_delete: :cascade add_foreign_key "operations_feature_flags", "projects", on_delete: :cascade
add_foreign_key "operations_feature_flags_clients", "projects", on_delete: :cascade add_foreign_key "operations_feature_flags_clients", "projects", on_delete: :cascade
add_foreign_key "packages_build_infos", "ci_pipelines", column: "pipeline_id", on_delete: :nullify
add_foreign_key "packages_build_infos", "packages_packages", column: "package_id", on_delete: :cascade
add_foreign_key "packages_conan_file_metadata", "packages_package_files", column: "package_file_id", on_delete: :cascade add_foreign_key "packages_conan_file_metadata", "packages_package_files", column: "package_file_id", on_delete: :cascade
add_foreign_key "packages_conan_metadata", "packages_packages", column: "package_id", on_delete: :cascade add_foreign_key "packages_conan_metadata", "packages_packages", column: "package_id", on_delete: :cascade
add_foreign_key "packages_dependency_links", "packages_dependencies", column: "dependency_id", on_delete: :cascade add_foreign_key "packages_dependency_links", "packages_dependencies", column: "dependency_id", on_delete: :cascade
......
# frozen_string_literal: true
class Packages::BuildInfo < ApplicationRecord
belongs_to :package, inverse_of: :build_info
belongs_to :pipeline, class_name: 'Ci::Pipeline'
end
...@@ -8,6 +8,7 @@ class Packages::Package < ApplicationRecord ...@@ -8,6 +8,7 @@ class Packages::Package < ApplicationRecord
has_many :dependency_links, inverse_of: :package, class_name: 'Packages::DependencyLink' has_many :dependency_links, inverse_of: :package, class_name: 'Packages::DependencyLink'
has_one :conan_metadatum, inverse_of: :package has_one :conan_metadatum, inverse_of: :package
has_one :maven_metadatum, inverse_of: :package has_one :maven_metadatum, inverse_of: :package
has_one :build_info, inverse_of: :package
accepts_nested_attributes_for :conan_metadatum accepts_nested_attributes_for :conan_metadatum
accepts_nested_attributes_for :maven_metadatum accepts_nested_attributes_for :maven_metadatum
......
...@@ -5,7 +5,7 @@ module Packages ...@@ -5,7 +5,7 @@ module Packages
app_group, _, app_name = params[:name].rpartition('/') app_group, _, app_name = params[:name].rpartition('/')
app_group.tr!('/', '.') app_group.tr!('/', '.')
project.packages.create!( package = project.packages.create!(
name: params[:name], name: params[:name],
version: params[:version], version: params[:version],
package_type: :maven, package_type: :maven,
...@@ -16,6 +16,11 @@ module Packages ...@@ -16,6 +16,11 @@ module Packages
app_version: params[:version] app_version: params[:version]
} }
) )
build = params[:build]
package.create_build_info!(pipeline: build.pipeline) if build.present?
package
end end
end end
end end
...@@ -5,6 +5,7 @@ module Packages ...@@ -5,6 +5,7 @@ module Packages
name = params[:name] name = params[:name]
version = params[:versions].keys.first version = params[:versions].keys.first
version_data = params[:versions][version] version_data = params[:versions][version]
build = params[:build]
existing_package = project.packages.npm.with_name(name).with_version(version) existing_package = project.packages.npm.with_name(name).with_version(version)
...@@ -16,6 +17,10 @@ module Packages ...@@ -16,6 +17,10 @@ module Packages
package_type: 'npm' package_type: 'npm'
) )
if build.present?
package.create_build_info!(pipeline: build.pipeline)
end
package_file_name = "#{name}-#{version}.tgz" package_file_name = "#{name}-#{version}.tgz"
attachment = params['_attachments'][package_file_name] attachment = params['_attachments'][package_file_name]
......
...@@ -25,7 +25,8 @@ module Packages ...@@ -25,7 +25,8 @@ module Packages
package_params = { package_params = {
name: package_name, name: package_name,
path: params[:path], path: params[:path],
version: version version: version,
build: params[:build]
} }
package = ::Packages::CreateMavenPackageService package = ::Packages::CreateMavenPackageService
......
...@@ -204,7 +204,7 @@ module API ...@@ -204,7 +204,7 @@ module API
bad_request!('Missing package file!') unless uploaded_file bad_request!('Missing package file!') unless uploaded_file
package = ::Packages::FindOrCreateMavenPackageService package = ::Packages::FindOrCreateMavenPackageService
.new(user_project, current_user, params).execute .new(user_project, current_user, params.merge(build: current_authenticated_job)).execute
case format case format
when 'sha1' when 'sha1'
......
...@@ -84,7 +84,7 @@ module API ...@@ -84,7 +84,7 @@ module API
authorize_create_package! authorize_create_package!
created_package = ::Packages::CreateNpmPackageService created_package = ::Packages::CreateNpmPackageService
.new(user_project, current_user, params).execute .new(user_project, current_user, params.merge(build: current_authenticated_job)).execute
if created_package[:status] == :error if created_package[:status] == :error
render_api_error!(created_package[:message], created_package[:http_status]) render_api_error!(created_package[:message], created_package[:http_status])
......
...@@ -417,6 +417,7 @@ describe API::MavenPackages do ...@@ -417,6 +417,7 @@ describe API::MavenPackages do
upload_file(params.merge(job_token: job.token)) upload_file(params.merge(job_token: job.token))
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(package.build_info.pipeline).to eq job.pipeline
end end
context 'version is not correct' do context 'version is not correct' do
......
...@@ -234,6 +234,27 @@ describe API::NpmPackages do ...@@ -234,6 +234,27 @@ describe API::NpmPackages do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
context 'with an authenticated job token' do
let!(:job) { create(:ci_build, user: user) }
before do
Grape::Endpoint.before_each do |endpoint|
expect(endpoint).to receive(:current_authenticated_job) { job }
end
end
after do
Grape::Endpoint.before_each nil
end
it 'creates the package metadata' do
upload_package_with_token(package_name, params)
expect(response).to have_gitlab_http_status(200)
expect(project.reload.packages.find(json_response['id']).build_info.pipeline).to eq job.pipeline
end
end
end end
context 'package creation fails' do context 'package creation fails' do
......
...@@ -10,6 +10,8 @@ describe Packages::CreateMavenPackageService do ...@@ -10,6 +10,8 @@ describe Packages::CreateMavenPackageService do
let(:path_with_version) { "#{path}/#{version}" } let(:path_with_version) { "#{path}/#{version}" }
describe '#execute' do describe '#execute' do
subject(:package) { described_class.new(project, user, params).execute }
context 'with version' do context 'with version' do
let(:params) do let(:params) do
{ {
...@@ -20,8 +22,6 @@ describe Packages::CreateMavenPackageService do ...@@ -20,8 +22,6 @@ describe Packages::CreateMavenPackageService do
end end
it 'creates a new package with metadatum' do it 'creates a new package with metadatum' do
package = described_class.new(project, user, params).execute
expect(package).to be_valid expect(package).to be_valid
expect(package.name).to eq(path) expect(package.name).to eq(path)
expect(package.version).to eq(version) expect(package.version).to eq(version)
...@@ -32,6 +32,8 @@ describe Packages::CreateMavenPackageService do ...@@ -32,6 +32,8 @@ describe Packages::CreateMavenPackageService do
expect(package.maven_metadatum.app_name).to eq(app_name) expect(package.maven_metadatum.app_name).to eq(app_name)
expect(package.maven_metadatum.app_version).to eq(version) expect(package.maven_metadatum.app_version).to eq(version)
end end
it_behaves_like 'assigns build to package'
end end
context 'without version' do context 'without version' do
......
...@@ -32,8 +32,11 @@ describe Packages::CreateNpmPackageService do ...@@ -32,8 +32,11 @@ describe Packages::CreateNpmPackageService do
describe '#execute' do describe '#execute' do
context 'scoped package' do context 'scoped package' do
let(:package_name) { "@#{namespace.path}/my-app".freeze } let(:package_name) { "@#{namespace.path}/my-app".freeze }
let(:package) { subject }
it_behaves_like 'valid package' it_behaves_like 'valid package'
it_behaves_like 'assigns build to package'
end end
context 'invalid package name' do context 'invalid package name' do
......
# frozen_string_literal: true # frozen_string_literal: true
shared_examples 'assigns build to package' 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
expect(package.build_info).to be_present
expect(package.build_info.pipeline).to eq job.pipeline
end
end
end
shared_examples 'returns packages' do |container_type, user_type| shared_examples 'returns packages' do |container_type, user_type|
context "for #{user_type}" do context "for #{user_type}" do
before do before do
......
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