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 =

Returns Target installation directory for packages.

Returns:

  • (String)

    Target installation directory for packages.

'/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', 'Gemfile.integration.lock',
  # CI/CD
  '.gitlab-ci*',
  # CI artifacts — never ship test/lint output
  'rspec-report.xml', 'rubocop-report.json',
  # 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',
  # Dev-only documentation (not needed at runtime)
  'doc/api', 'doc/reference', 'doc/context', 'doc/issues',
  'doc/decisions', 'doc/changes',
  # Security advisories — internal, never ship publicly
  'doc/security',
  # Design docs — carry internal WP refs, not runtime-required
  'conf/design',
  # Behaviour rules — user-authored, must never ship in packages (sec_001/rule_073)
  'conf/behaviour',
  # Peer review configs (dev-only)
  'conf/review',
  # AI assistant state — never ship in package
  '.claude', 'doc/claude-sessions',
  # AI provenance file — dev-only provenance tracking, not runtime-required
  '.ai-provenance.yml',
  # Internal audit, operations, signing, and rule-audit documents
  'doc/audits', 'doc/operations', 'doc/signing',
  'doc/rules-audit-*.md',
  '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_systemd, :install_man, :install_build_info, :rewrite_shebangs, :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

#createvoid

This method returns an undefined value.

Build a .deb package for the specified variant.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/rosett_ai/thor/tasks/build.rb', line 192

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_systemd) { install_systemd_unit! }
  run_stage(:install_man) { install_man_pages! }
  run_stage(:install_build_info) { install_build_info! }
  run_stage(:rewrite_shebangs) { rewrite_shebangs! }
  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