Class: RosettAi::Thor::Tasks::BuildPackage

Inherits:
Thor
  • Object
show all
Includes:
Formatting
Defined in:
lib/rosett_ai/thor/tasks/build.rb

Overview

Thor subcommand for building a .deb package using fpm + ruby-build.

Produces a self-contained Debian package at /opt/rosett-ai with an embedded Ruby runtime (compiled via ruby-build), vendored gems, and maintainer scripts for proper APT lifecycle handling.

Build tooling references: fpm — https://github.com/jordansissel/fpm ruby-build — https://github.com/rbenv/ruby-build dpkg-deb — https://man7.org/linux/man-pages/man1/dpkg-deb.1.html fakeroot — https://wiki.debian.org/FakeRoot

Constant Summary collapse

INSTALL_DIR =
'/opt/rosett-ai'
APP_EXCLUDES =

Files/directories excluded when syncing app source into the staging tree

[
  # Version control
  '.git', '.gitignore',
  # Bundler / gem build artifacts
  '.bundle', '.binstubs', 'vendor/bundle', '*.gem',
  'Gemfile.dev', 'Gemfile.dev.lock', 'Gemfile.integration',
  # CI/CD
  '.gitlab-ci*',
  # Build & packaging
  'coverage', 'tmp', 'pkg', 'spec', 'test', 'packaging',
  # Dev tool configs
  '.rspec', '.rubocop*', '.reek*',
  '.fasterer.yml', '.gitleaks.toml', '.mutant.yml',
  '.overcommit.yml', '.git-hooks',
  '.mdlrc', '.mdl_style.rb', '.yamllint', '.yardopts',
  '.project', '.rosett-ai',
  # AI assistant state — never ship in package
  '.claude', 'doc/claude-sessions',
  'cliff.toml', 'kitchen.yml', 'Rakefile'
].freeze
BUILD_STAGES =

Build stages in execution order (for tracking)

[
  :validate, :clean, :prepare, :compile_ruby,
  :sync_app, :install_gems, :clean_build_artifacts,
  :install_wrapper,
  :install_config, :install_man, :install_build_info, :package
].freeze
BUNDLER_ENV_VARS =

Bundler/RubyGems environment variables that must be stripped when shelling out to the embedded Ruby. Without this, a parent bundle exec leaks RUBYOPT=-rbundler/setup and BUNDLE_* vars into child processes, causing the embedded Ruby to try loading the project's Gemfile (which it cannot resolve).

[
  'BUNDLE_GEMFILE', 'BUNDLE_PATH', 'BUNDLE_BIN_PATH',
  'BUNDLE_APP_CONFIG',
  'BUNDLE_DEPLOYMENT', 'BUNDLE_WITHOUT', 'BUNDLE_FROZEN',
  'BUNDLE_DISABLE_SHARED_GEMS', 'BUNDLE_IGNORE_CONFIG',
  'BUNDLER_ORIG_BUNDLE_GEMFILE', 'BUNDLER_ORIG_BUNDLE_BIN_PATH',
  'BUNDLER_ORIG_BUNDLER_SETUP', 'BUNDLER_ORIG_BUNDLER_VERSION',
  'BUNDLER_ORIG_GEM_HOME', 'BUNDLER_ORIG_GEM_PATH',
  'BUNDLER_ORIG_MANPATH', 'BUNDLER_ORIG_PATH',
  'BUNDLER_ORIG_RB_USER_INSTALL',
  'BUNDLER_ORIG_RUBYLIB', 'BUNDLER_ORIG_RUBYOPT',
  'BUNDLER_VERSION',
  'BUNDLER_SETUP', 'GEM_HOME', 'GEM_PATH',
  'RUBYOPT', 'RUBYLIB'
].freeze
HERMETIC_SYSTEM_PATH =

Hermetic system PATH — no workstation paths allowed. Native gem compilation needs basic system tools (make, gcc, ld) but must never reference /home/*, ~/.rbenv, or other user paths.

'/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'

Constants included from Formatting

Formatting::SIZE_UNITS

Instance Method Summary collapse

Methods included from Formatting

#format_duration, #format_size

Instance Method Details

#createObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rosett_ai/thor/tasks/build.rb', line 165

def create
  unless RosettAi.context.rai_internal?
    raise ::Thor::Error,
          ::I18n.t('rosett_ai.cli.build_package_internal_only')
  end

  init_build_context!
  load_variant_config!
  print_build_header

  run_stage(:validate) { validate_environment! }
  run_stage(:clean) { clean_staging! } if options[:clean]
  run_stage(:prepare) { prepare_staging! }
  run_stage(:compile_ruby) { compile_ruby! }
  run_stage(:sync_app) { sync_application! }
  run_stage(:install_gems) { install_gems! }
  run_stage(:clean_build_artifacts) { clean_build_artifacts! }
  run_stage(:install_wrapper) { install_wrapper! }
  run_stage(:install_config) { install_default_config! }
  run_stage(:install_man) { install_man_pages! }
  run_stage(:install_build_info) { install_build_info! }
  run_stage(:package) { build_package! }

  print_build_summary(:success)
rescue ::Thor::Error => e
  print_build_summary(:failed) if @ctx && !@ctx.summary_printed
  raise e
end