Class: Everywhere::Commands::PlatformRunner
- Inherits:
-
Dry::CLI::Command
- Object
- Dry::CLI::Command
- Everywhere::Commands::PlatformRunner
- Defined in:
- lib/everywhere/commands/platform/runner.rb
Overview
every platform runner — runs ON a build runner: a macOS machine for the
macos/ios targets, macOS or Linux for android. It's the glue between the
Runner API and the every release signing engine:
job spec → mark running → download+extract snapshot → pull JIT creds into
a throwaway keychain (+ .p8) → every release (streaming logs) → upload the
artifact + release.json → complete.
Authenticated with the per-artifact runner token, so it can only touch the one artifact it was dispatched for.
Constant Summary collapse
- ARTIFACTS =
What
every releaseleaves in dist/ per os, newest first when several match, and how the blob store should label it. { "macos" => %w[*.zip], "ios" => %w[*.ipa], "android" => %w[*.aab *.apk] }.freeze
- CONTENT_TYPES =
{ ".zip" => "application/zip", ".ipa" => "application/octet-stream", ".apk" => "application/vnd.android.package-archive", ".aab" => "application/octet-stream" }.freeze
- RELEASE_NARRATION =
{ "macos" => "every release — press → sign → notarize → staple", "ios" => "every release — build → archive → export .ipa", "android" => "every release — assemble → sign → bundle" }.freeze
- PROFILE_DIRS =
A .mobileprovision has to be in both: Xcode reads the UserData copy, xcodebuild's own resolution still reads the MobileDevice one.
[ "~/Library/MobileDevice/Provisioning Profiles", "~/Library/Developer/Xcode/UserData/Provisioning Profiles" ].freeze
- PROFILE_UUID =
/\A[0-9a-f-]+\z/i
Instance Method Summary collapse
Instance Method Details
#call(artifact:, token:, url: nil, shell_dir: nil) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/everywhere/commands/platform/runner.rb', line 62 def call(artifact:, token:, url: nil, shell_dir: nil, **) # We run headless on a build runner (a pipe, not a TTY) and stream into # the Platform web log, which renders ANSI. Force color on so the hosted # log reads like a local run. ENV["CLICOLOR_FORCE"] ||= "1" unless ENV["NO_COLOR"] base = Everywhere::Platform::Client.base_url(url) @client = Everywhere::Platform::Client.new(base, token: token) @artifact = artifact job = get!("/runner/artifacts/#{artifact}") patch!("/runner/artifacts/#{artifact}", status: "running") remote_log("picked up #{UI.cyan("#{UI.os_label(job.dig("target", "os"))}-#{job.dig("target", "arch")}")} for #{UI.bold(job.dig("app", "name"))}") Dir.mktmpdir("every-runner") do |work| src = fetch_snapshot(work, job) signing_env = pull_credentials(work) status, release_json, built = run_release(src, job, signing_env, shell_dir) if status == "succeeded" && built complete_success(built, release_json) else complete_failure("build failed — see log") end ensure restore_keychains end rescue Everywhere::Error => e complete_failure(e.) UI.die!(e.) rescue Everywhere::Fatal => e # UI.die! raises Fatal (a SystemExit), which the rescue above can't see — # without this an upload/signing failure would leave the artifact stuck # "running" on the Platform forever. complete_failure(e..to_s.empty? ? "build failed" : e.) raise end |