defmodule Mix.Tasks.ReleaseKit.Artifact do
@moduledoc """
Builds an OTP release tarball and ReleaseKit ETF manifest.
MIX_ENV=prod mix release_kit.artifact --out-dir _build/prod/artifacts
The task intentionally stops at producing files. Deployment tools are
responsible for unpacking, configuring, and supervising the release.
Existing artifacts from a clean checkout are reused by default. Pass
`--force` to rebuild even when the current manifest and tarball match the
checkout.
"""
use Mix.Task
alias ReleaseKit.Builder
@shortdoc "Builds an OTP release artifact and manifest"
@impl true
def run(args) do
{opts, rest, invalid} =
OptionParser.parse(args,
strict: [
out_dir: :string,
release: :string,
version: :string,
port: :integer,
health_path: :string,
skip_release: :boolean,
force: :boolean,
target_os: :string,
target_arch: :string,
target_libc: :string,
target_suffix: :boolean
]
)
if invalid != [], do: Mix.raise("Invalid options: #{inspect(invalid)}")
if rest != [], do: Mix.raise("Unexpected arguments: #{inspect(rest)}")
result =
Builder.build(
out_dir: Keyword.get(opts, :out_dir),
release: Keyword.get(opts, :release),
version: Keyword.get(opts, :version),
port: Keyword.get(opts, :port),
health_path: Keyword.get(opts, :health_path),
force?: Keyword.get(opts, :force, false),
target: target(opts),
target_suffix?: Keyword.get(opts, :target_suffix, false),
build_release?: not Keyword.get(opts, :skip_release, false)
)
Mix.shell().info("Release tarball: #{result.tarball}")
Mix.shell().info("ReleaseKit manifest: #{result.manifest_path}")
end
defp target(opts) do
target = [
os: Keyword.get(opts, :target_os),
arch: Keyword.get(opts, :target_arch),
libc: Keyword.get(opts, :target_libc)
]
target = Enum.reject(target, fn {_key, value} -> is_nil(value) end)
if target == [], do: nil, else: target
end
end