Skip to content

Commit

Permalink
[api] support manual package release according to Fate #315081
Browse files Browse the repository at this point in the history
This requires that the repository release target is defined and the trigger is set to "manual".
Comes with some cleanups of code
  • Loading branch information
adrianschroeter committed Jun 10, 2013
1 parent 42cd38a commit fb981ad
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 12 deletions.
14 changes: 14 additions & 0 deletions docs/api/api/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,19 @@ Parameters:
Result: diff as text/plain


POST /source/<project>/<package>?cmd=release

Releases sources and binaries of that package. This requires a set
release target in the repository definitions of <project>. Also the
trigger must be set to "manual"

Parameters:
comment: description for the history
repository: limit the release to the specified repository

XmlResult: status


POST /source/<project>/<package>?cmd=unlock

Unlocks a locked package
Expand Down Expand Up @@ -697,6 +710,7 @@ POST /source/<project>/<package>
copy: copy package sources from another package
undelete: undelete the package
unlock: unlock a package with lock enabled. A comment is required.
release: release sources and binaries according to release target specification
branch: branch a package into another one
linktobranch: convert a plain source link into a full branch
updatepatchinfo: update _patchinfo file, esp. the issues list
Expand Down
6 changes: 3 additions & 3 deletions docs/api/api/obs.rng
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@

<define ns="" name="release-triggers">
<choice>
<value>manual</value> <!-- DEFAULT: only on manual commands the release gets started -->
<value>finished</value> <!-- Release when the repository has finished building -->
<value>allsucceeded</value> <!-- Release when the repository has finished building and all jobs were successfull -->
<!-- DEFAULT: not set, no release action possible -->
<value>manual</value> <!-- only on manual commands the release gets started -->
<!-- no yet supported <value>allsucceeded</value> --> <!-- Release when the repository has finished building and all jobs were successfull -->
<value>maintenance</value> <!-- Release just once on maintenance release event. This attribute get removed at the same time -->
</choice>
</define>
Expand Down
49 changes: 46 additions & 3 deletions src/api/app/controllers/source_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def index_package
valid_commands=['diff', 'branch', 'servicediff', 'linkdiff', 'showlinked', 'copy', 'remove_flag', 'set_flag',
'rebuild', 'undelete', 'wipe', 'runservice', 'commit', 'commitfilelist',
'createSpecFileTemplate', 'deleteuploadrev', 'linktobranch', 'updatepatchinfo',
'getprojectservices', 'unlock']
'getprojectservices', 'unlock', 'release']
# list of commands which are allowed even when the project has the package only via a project link
read_commands = ['branch', 'diff', 'linkdiff', 'servicediff', 'showlinked', 'getprojectservices']
source_untouched_commands = ['branch', 'diff', 'linkdiff', 'servicediff', 'showlinked', 'rebuild', 'wipe', 'remove_flag', 'set_flag', 'getprojectservices']
Expand All @@ -258,7 +258,10 @@ def index_package
raise MissingParameterError.new "POST request without given cmd parameter"
end
# find out about source and target dependening on command - FIXME: ugly! sync calls
if command == 'branch'
if command == 'release'
origin_project_name = params[:project]
origin_package_name = params[:package]
elsif command == 'branch'
origin_project_name = params[:project]
target_package_name = origin_package_name = params[:package]
target_project_name = params[:target_project] if params[:target_project]
Expand Down Expand Up @@ -291,7 +294,30 @@ def index_package
tprj = nil
tpkg = nil
# The target must exist, except for following cases
if (request.post? and command == 'undelete') or (request.get? and deleted_package)
if (request.post? and command == 'release')
repo_matches=nil
spkg.project.repositories.each do |repo|
next if params[:repository] and params[:repository] != repo.name
repo.release_targets.each do |releasetarget|
unless @http_user.can_modify_project?(releasetarget.target_repository.project)
render_error :status => 403, :errorcode => "cmd_execution_no_permission",
:message => "no permission to write in project #{releasetarget.target_repository.project.name}"
return
end
unless releasetarget.trigger == "manual"
render_error :status => 400, :errorcode => "cmd_execution_no_permission",
:message => "Trigger is not set to manual in repository #{releasetarget.repository.project.name}/#{releasetarget.repository.name}"
return
end
repo_matches=true
end
end
unless repo_matches
render_error :status => 404, :errorcode => "no_matching_release_target",
:message => "No defined or matching release target"
return
end
elsif (request.post? and command == 'undelete') or (request.get? and deleted_package)
tprj = Project.get_by_name(target_project_name)
if Package.exists_by_project_and_name(target_project_name, target_package_name, follow_project_links: false)
render_error :status => 404, :errorcode => "package_exists",
Expand Down Expand Up @@ -1830,6 +1856,23 @@ def index_package_copy
tpkg.sources_changed
end

# POST /source/<project>/<package>?cmd=release
def index_package_release
valid_http_methods :post
params[:user] = @http_user.login

pkg = Package.get_by_project_and_name params[:project], params[:package], use_source: true, follow_project_links: false
pkg.project.repositories.each do |repo|
next if params[:repository] and params[:repository] != repo.name
repo.release_targets.each do |releasetarget|
# find md5sum and release source and binaries
release_package(pkg, releasetarget.target_repository.project.name, pkg.name, repo)
end
end

render_ok
end

# POST /source/<project>/<package>?cmd=runservice
def index_package_runservice
valid_http_methods :post
Expand Down
7 changes: 4 additions & 3 deletions src/api/app/helpers/maintenance_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ def do_branch params
trepo.repository_architectures.create :architecture => ra.architecture, :position => ra.position
end
trepo.path_elements.create(:link => repo, :position => 1)
trigger = nil # manual
trigger = nil # no trigger is set by default
trigger = "maintenance" if MaintenanceIncident.find_by_db_project_id( tprj.id ) # is target an incident project ?
trepo.release_targets.create(:target_repository => repo, :trigger => trigger) if p[:link_target_project].project_type == "maintenance_release"
end
Expand Down Expand Up @@ -604,8 +604,8 @@ def do_branch params
return { :status => 200, :data => response }
end

def release_package(sourcePackage, targetProjectName, targetPackageName, revision,
sourceRepository, releasetargetRepository, timestamp, request = nil)
def release_package(sourcePackage, targetProjectName, targetPackageName,
filterSourceRepository = nil, request = nil)

targetProject = Project.get_by_name targetProjectName

Expand Down Expand Up @@ -682,6 +682,7 @@ def release_package(sourcePackage, targetProjectName, targetPackageName, revisio

# copy binaries
sourcePackage.project.repositories.each do |sourceRepo|
next if filterSourceRepository and filterSourceRepository != sourceRepo
sourceRepo.release_targets.each do |releasetarget|
#FIXME2.5: filter given release and/or target repos here
sourceRepo.architectures.each do |arch|
Expand Down
3 changes: 1 addition & 2 deletions src/api/app/models/bs_request_action_maintenance_release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ def execute_changestate(opts)
# have a unique time stamp for release
opts[:acceptTimeStamp] ||= Time.now

release_package(pkg, self.target_project, self.target_package,
self.source_rev, nil, nil, opts[:acceptTimeStamp], self.bs_request)
release_package(pkg, self.target_project, self.target_package, nil, self.bs_request)
opts[:projectCommit] ||= {}
opts[:projectCommit][self.target_project] = self.source_project
end
Expand Down
7 changes: 7 additions & 0 deletions src/api/db/migrate/20130610100244_manual_release_trigger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class ManualReleaseTrigger < ActiveRecord::Migration

def self.up
execute "alter table release_targets modify column `trigger` enum('manual','allsucceeded','maintenance') DEFAULT NULL;"
end

end
4 changes: 3 additions & 1 deletion src/api/db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ CREATE TABLE `release_targets` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`repository_id` int(11) NOT NULL,
`target_repository_id` int(11) NOT NULL,
`trigger` enum('finished','allsucceeded','maintenance') DEFAULT NULL,
`trigger` enum('manual','allsucceeded','maintenance') DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `repository_id_index` (`repository_id`),
KEY `index_release_targets_on_target_repository_id` (`target_repository_id`),
Expand Down Expand Up @@ -1064,6 +1064,8 @@ INSERT INTO schema_migrations (version) VALUES ('20130414061002');

INSERT INTO schema_migrations (version) VALUES ('20130603100244');

INSERT INTO schema_migrations (version) VALUES ('20130610100244');

INSERT INTO schema_migrations (version) VALUES ('21');

INSERT INTO schema_migrations (version) VALUES ('22');
Expand Down
74 changes: 74 additions & 0 deletions src/api/test/functional/source_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1965,6 +1965,80 @@ def test_linktobranch
assert_response :success
end

def test_release_package
# define release target
prepare_request_with_user "king", "sunflower"

prepare_request_with_user "Iggy", "asdfasdf"
# create and define manual release target
put "/source/home:Iggy:RT/_meta", "<project name='home:Iggy:RT'> <title/> <description/>
<repository name='rt'>
<arch>i586</arch>
<arch>x86_64</arch>
</repository>
</project>"
assert_response :success

run_scheduler("i586")
run_scheduler("x86_64")

get "/source/home:Iggy/_meta"
assert_response :success
orig_project_meta = @response.body
doc = REXML::Document.new( @response.body )
rt = doc.elements["/project/repository'"].add_element "releasetarget"
rt.add_attribute REXML::Attribute.new('project', 'home:Iggy:RT')
rt.add_attribute REXML::Attribute.new('repository', 'rt')
put "/source/home:Iggy/_meta", doc.to_s
assert_response :success

# try to release with incorrect trigger
post "/source/home:Iggy/TestPack?cmd=release", nil
assert_response 400
assert_match(/Trigger is not set to manual in repository home:Iggy\/10.2/, @response.body)

# add correct trigger
rt.add_attribute REXML::Attribute.new('trigger', 'manual')
put "/source/home:Iggy/_meta", doc.to_s
assert_response :success

# this user is not allowed
prepare_request_with_user "adrian", "so_alone"
post "/source/home:Iggy/TestPack?cmd=release", nil
assert_response 403
assert_xml_tag :tag => "status", :attributes => { :code => "cmd_execution_no_permission" }

# release for real
prepare_request_with_user "Iggy", "asdfasdf"
post "/source/home:Iggy/TestPack?cmd=release", nil
assert_response :success
assert_xml_tag :tag => "status", :attributes => { :code => "ok" }

# process events
run_scheduler("i586")

# verify result
get "/source/home:Iggy:RT"
assert_response :success
assert_xml_tag :tag => "entry", :attributes => { :name => "TestPack" }

# compare source with target repo
get "/build/home:Iggy/10.2/i586/TestPack/"
assert_response :success
assert_xml_tag :tag => "binarylist", :children => { :count => 4 }

get "/build/home:Iggy:RT/rt/i586/TestPack/"
assert_response :success
assert_xml_tag :tag => "binarylist", :children => { :count => 4 }

# cleanup
prepare_request_with_user "Iggy", "asdfasdf"
put "/source/home:Iggy/_meta", orig_project_meta
assert_response :success
delete "/source/home:Iggy:RT"
assert_response :success
end

def test_copy_package
# fred has maintainer permissions in this single package of Iggys home
# this is the osc way
Expand Down

0 comments on commit fb981ad

Please sign in to comment.