Class: Everywhere::Commands::Release

Inherits:
Dry::CLI::Command
  • Object
show all
Defined in:
lib/everywhere/commands/release.rb

Overview

Produce a signed, notarized, stapled, distributable artifact + release.json.

every release wraps the existing signing engine (cli/support/release/macos/notarize.sh) rather than reimplementing codesign/notarytool, and emits the machine-readable receipt every build surface (local, CI, Platform) must produce. See platform/docs/build-engine.md §4, §7, §9.

macos/ios/android are live; windows/linux slot in as builders later.

Constant Summary collapse

NOTARIZE =
File.expand_path("../../../support/release/macos/notarize.sh", __dir__)
ARTIFACTS =

What counts as "the distributable" per os, newest first when several match. Android is listed aab-then-apk so a --format aab run picks the bundle even when an older apk is still sitting in dist/.

{ "macos" => %w[*.zip], "ios" => %w[*.ipa], "android" => %w[*.aab *.apk] }.freeze

Instance Method Summary collapse

Instance Method Details

#call(root: ".", target: Build::DEFAULT_TARGET, channel: "direct", ruby: nil, entry: "native_boot.rb", app_name: nil, shell_dir: nil, env_file: nil, format: "apk", skip_build: false) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/everywhere/commands/release.rb', line 45

def call(root: ".", target: Build::DEFAULT_TARGET, channel: "direct", ruby: nil, entry: "native_boot.rb",
         app_name: nil, shell_dir: nil, env_file: nil, format: "apk", skip_build: false, **)
  root_path = File.expand_path(root)
  config = Everywhere::Config.load(root_path)
  app_name ||= config.name(target: target)
  ruby ||= config.build_ruby || "4.0.6"
  os = Everywhere::Config.os_of(target)

  preflight!(target, os)

  framework = config.remote? ? nil : Framework.detect(root_path)
  dist_dir = File.expand_path("dist", root_path)

  # 1. Produce (or reuse) the build. macOS gets a dev-signed .app that the
  #    notarize step re-signs inside-out with the Developer ID; the mobile
  #    toolchains sign as they build, so their artifact is already final.
  unless skip_build
    UI.phase("Building #{app_name} for #{UI.target_label(target)}")
    Build.new.call(root: root, ruby: ruby, entry: entry, app_name: app_name, target: target,
                   shell_dir: shell_dir, **, **build_options(os, format, channel))
  end

  # 2. Sign/notarize (macOS) or locate what the mobile builder signed, then
  #    3. record the signing facts and emit the receipt.
  artifact, signing = case os
                      when "macos" then notarize!(dist_dir, root_path, env_file)
                      when "ios"   then [find_artifact(dist_dir, os), ios_signing(dist_dir)]
                      else              [find_artifact(dist_dir, os), android_signing]
                      end

  receipt = Receipt.new(root: root_path, config: config, framework: framework, ruby: ruby,
                        target: target, channel: channel, shell_dir: resolve_shell_dir(shell_dir))
  out = File.join(dist_dir, "release.json")
  receipt.write(out, artifact: artifact, signing: signing)

  summarize(out, artifact, signing, root_path)
end