class Issuer::Processor


results = processor.process_data(yaml_data, proj: ‘myorg/myrepo’)
processor = Issuer::Processor.new(site: site)
site = Issuer::Sites::Factory.create(:github, token: ‘custom-token’)
@example With custom site
results = processor.process_file(‘issues.yml’, proj: ‘myorg/myrepo’)
processor = Issuer::Processor.new
@example Basic usage
This is the recommended entry point for programmatic access to Issuer functionality.
Main processor class that provides a clean API for external usage.
#

def get_site

def get_site
  @site ||= Sites::Factory.create(Sites::Factory.default_site)
end

def initialize site: nil, cache: true

Parameters:
  • cache (Boolean) -- Whether to enable run tracking and caching (default: true)
  • site (Issuer::Sites::Base, nil) -- Custom site adapter. If nil, will auto-detect.
def initialize site: nil, cache: true
  @site = site
  @cache_enabled = cache
end

def perform_dry_run issues, repo

def perform_dry_run issues, repo
  site = Sites::Factory.create('github', token: 'dry-run-token')
  puts "🧪 DRY RUN - No issues will be created"
  puts "📋 Target repository: #{repo}" if repo
  puts "📝 Would create #{issues.length} issues:"
  puts
  issues.each_with_index do |issue, idx|
    params = site.convert_issue_to_site_params(issue, repo, dry_run: true)
    puts "#{idx + 1}. #{params[:title]}"
    puts "   Labels: #{params[:labels].join(', ')}" if params[:labels]&.any?
    puts "   Assignee: #{params[:assignee]}" if params[:assignee]
    puts "   Milestone: #{params[:milestone]}" if params[:milestone]
    puts
  end
  {
    dry_run: true,
    issues_planned: issues.length,
    target_repo: repo,
    valid_issues: issues.length
  }
end

def perform_live_run issues, repo, automation_options

def perform_live_run issues, repo, automation_options
  site = get_site
  # Start run tracking if caching enabled
  run_id = if @cache_enabled
    Cache.start_run(issues_planned: issues.length, target_repo: repo)
  else
    nil
  end
  begin
    # Validate and prepare resources (milestones, labels)
    Ops.validate_and_prepare_resources(site, repo, issues, automation_options, run_id) unless issues.empty?
    # Create issues
    processed_count = site.post_issues(repo, issues, run_id)
    # Complete run tracking
    Cache.complete_run(run_id, processed_count) if run_id
    {
      dry_run: false,
      issues_created: processed_count,
      issues_planned: issues.length,
      target_repo: repo,
      run_id: run_id
    }
  rescue => e
    # Mark run as failed
    Cache.fail_run(run_id, e.message) if run_id
    raise
  end
end

def process_data data, proj: nil, dry_run: false, automation_options: {}

Raises:
  • (Issuer::Error) - If data is invalid or processing fails

Returns:
  • (Hash) - Results including created issues, milestones, labels, and run metadata

Parameters:
  • automation_options (Hash) -- Options for automatic resource creation
  • dry_run (Boolean) -- If true, validate and show what would be created without API calls
  • proj (String, nil) -- Target repository (org/repo format)
  • data (Hash) -- Parsed IMYML data structure
def process_data data, proj: nil, dry_run: false, automation_options: {}
  # Extract metadata and issues
  meta = data['$meta'] || {}
  issues_data = data['issues'] || data
  unless issues_data.is_a?(Array)
    raise Error, 'No issues array found (root or under "issues")'
  end
  # Build defaults
  defaults = (meta['defaults'] || {}).dup
  defaults['proj'] = meta['proj'] if meta['proj']
  # Determine target repository
  target_repo = proj || meta['proj'] || ENV['ISSUER_REPO']
  if target_repo.nil? && !dry_run
    raise Error, 'No target repo specified. Use proj parameter, $meta.proj, or ISSUER_REPO environment variable.'
  end
  # Process issues
  issues = Ops.process_issues_data(issues_data, defaults)
  valid_issues = issues.select(&:valid?)
  invalid_issues = issues.reject(&:valid?)
  # Report validation errors
  invalid_issues.each_with_index do |issue, idx|
    puts "⚠️  Skipping invalid issue: #{issue.validation_errors.join(', ')}"
  end
  if dry_run
    return perform_dry_run(valid_issues, target_repo)
  else
    return perform_live_run(valid_issues, target_repo, automation_options)
  end
end

def process_file file_path, proj: nil, dry_run: false, automation_options: {}

Raises:
  • (Issuer::Error) - If file cannot be read or processed

Returns:
  • (Hash) - Results including created issues, milestones, labels, and run metadata

Options Hash: (**automation_options)
  • :auto_metadata (Boolean) -- Automatically create all missing metadata
  • :auto_tags (Boolean) -- Automatically create missing labels
  • :auto_versions (Boolean) -- Automatically create missing milestones

Parameters:
  • automation_options (Hash) -- Options for automatic resource creation
  • dry_run (Boolean) -- If true, validate and show what would be created without API calls
  • proj (String, nil) -- Target repository (org/repo format)
  • file_path (String) -- Path to the IMYML YAML file
def process_file file_path, proj: nil, dry_run: false, automation_options: {}
  require 'yaml'
  unless File.exist?(file_path)
    raise Error, "File not found: #{file_path}"
  end
  begin
    raw_data = YAML.load_file(file_path)
  rescue => e
    raise Error, "Could not parse YAML file: #{file_path}\n#{e.message}"
  end
  process_data(raw_data, proj: proj, dry_run: dry_run, automation_options: automation_options)
end