@@ -385,6 +385,57 @@ def auto_publish_composites!(component_task_id)
385385 end
386386 end
387387
388+ class << self
389+ # Trigger a composite publish with coordination for sibling tasks.
390+ # Checks for running component CV publishes and chains if necessary.
391+ def trigger_composite_publish_with_coordination ( composite_cv , description , triggered_by_version_id , calling_task_id : nil )
392+ # Find currently running component CV publish tasks
393+ component_cv_ids = composite_cv . components . pluck ( :content_view_id )
394+ running_tasks = ForemanTasks ::Task ::DynflowTask
395+ . for_action ( ::Actions ::Katello ::ContentView ::Publish )
396+ . where ( state : [ 'planning' , 'planned' , 'running' ] )
397+ . select do |task |
398+ task_input = task . input
399+ task_input && component_cv_ids . include? ( task_input . dig ( 'content_view' , 'id' ) )
400+ end
401+
402+ sibling_task_ids = running_tasks . map ( &:external_id )
403+ # Exclude the calling component task to avoid self-dependency
404+ sibling_task_ids . reject! { |id | id == calling_task_id } if calling_task_id
405+
406+ trigger_publish_with_sibling_tasks ( composite_cv , sibling_task_ids , description , triggered_by_version_id )
407+ rescue ForemanTasks ::Lock ::LockConflict => e
408+ Rails . logger . info ( "Composite CV #{ composite_cv . name } publish lock conflict: #{ e . class } - #{ e . message } " )
409+ ::Katello ::UINotifications ::ContentView ::AutoPublishFailure . deliver! ( composite_cv )
410+ raise
411+ rescue StandardError => e
412+ Rails . logger . error ( "Failed to auto-publish composite CV #{ composite_cv . name } : #{ e . class } - #{ e . message } " )
413+ Rails . logger . debug ( e . backtrace . join ( "\n " ) ) if e . backtrace
414+ ::Katello ::UINotifications ::ContentView ::AutoPublishFailure . deliver! ( composite_cv )
415+ raise
416+ end
417+
418+ # Trigger a composite publish, chaining to sibling tasks if any exist
419+ def trigger_publish_with_sibling_tasks ( composite_cv , sibling_task_ids , description , triggered_by_version_id )
420+ if sibling_task_ids . any?
421+ ForemanTasks . dynflow . world . chain (
422+ sibling_task_ids ,
423+ ::Actions ::Katello ::ContentView ::Publish ,
424+ composite_cv ,
425+ description ,
426+ triggered_by_id : triggered_by_version_id
427+ )
428+ else
429+ ForemanTasks . async_task (
430+ ::Actions ::Katello ::ContentView ::Publish ,
431+ composite_cv ,
432+ description ,
433+ triggered_by_id : triggered_by_version_id
434+ )
435+ end
436+ end
437+ end
438+
388439 private
389440
390441 # Returns :scheduled, :running, or nil based on composite CV publish task status
@@ -420,61 +471,11 @@ def scheduled_task_for_composite?(task, composite_cv)
420471
421472 args = delayed_plan . args
422473 args . first . is_a? ( ::Katello ::ContentView ) && args . first . id == composite_cv . id
423- rescue NoMethodError , TypeError , Dynflow ::Error
474+ rescue NoMethodError , TypeError , Dynflow ::Error => e
424475 Rails . logger . error ( "Failed to check scheduled task for composite CV #{ composite_cv . name } : #{ e . message } " )
425476 false
426477 end
427478
428- # Trigger a composite publish with coordination for sibling tasks.
429- # Checks for running component CV publishes and chains if necessary.
430- def self . trigger_composite_publish_with_coordination ( composite_cv , description , triggered_by_version_id , calling_task_id : nil )
431- # Find currently running component CV publish tasks
432- component_cv_ids = composite_cv . components . pluck ( :content_view_id )
433- running_tasks = ForemanTasks ::Task ::DynflowTask
434- . for_action ( ::Actions ::Katello ::ContentView ::Publish )
435- . where ( state : [ 'planning' , 'planned' , 'running' ] )
436- . select do |task |
437- task_input = task . input
438- task_input && component_cv_ids . include? ( task_input . dig ( 'content_view' , 'id' ) )
439- end
440-
441- sibling_task_ids = running_tasks . map ( &:external_id )
442- # Exclude the calling component task to avoid self-dependency
443- sibling_task_ids . reject! { |id | id == calling_task_id } if calling_task_id
444-
445- trigger_publish_with_sibling_tasks ( composite_cv , sibling_task_ids , description , triggered_by_version_id )
446- rescue ForemanTasks ::Lock ::LockConflict => e
447- Rails . logger . info ( "Composite CV #{ composite_cv . name } publish lock conflict: #{ e . class } - #{ e . message } " )
448- ::Katello ::UINotifications ::ContentView ::AutoPublishFailure . deliver! ( composite_cv )
449- raise
450- rescue StandardError => e
451- Rails . logger . error ( "Failed to auto-publish composite CV #{ composite_cv . name } : #{ e . class } - #{ e . message } " )
452- Rails . logger . debug ( e . backtrace . join ( "\n " ) ) if e . backtrace
453- ::Katello ::UINotifications ::ContentView ::AutoPublishFailure . deliver! ( composite_cv )
454- raise
455- end
456-
457- # Trigger a composite publish, chaining to sibling tasks if any exist
458- def self . trigger_publish_with_sibling_tasks ( composite_cv , sibling_task_ids , description , triggered_by_version_id )
459- if sibling_task_ids . any?
460- ForemanTasks . dynflow . world . chain (
461- sibling_task_ids ,
462- ::Actions ::Katello ::ContentView ::Publish ,
463- composite_cv ,
464- description ,
465- triggered_by_id : triggered_by_version_id
466- )
467- else
468- ForemanTasks . async_task (
469- ::Actions ::Katello ::ContentView ::Publish ,
470- composite_cv ,
471- description ,
472- triggered_by_id : triggered_by_version_id
473- )
474- end
475- end
476-
477-
478479 # Find active (planning/planned/running) composite publish tasks (does NOT check scheduled tasks)
479480 def find_active_composite_publish_tasks ( composite_cv )
480481 relevant_tasks = ForemanTasks ::Task ::DynflowTask
0 commit comments