Packages
nerves
1.7.14
1.15.0
1.14.3
1.14.2
1.14.1
1.14.0
1.13.2
1.13.1
1.13.0
1.12.0
1.11.3
1.11.2
1.11.1
1.11.0
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.3
1.9.2
retired
1.9.1
1.9.0
1.8.0
1.7.17
1.7.16
1.7.15
1.7.14
retired
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
retired
1.7.1
retired
1.7.0
retired
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.11.0
0.10.1
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.4.0-rc.0
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
Craft and deploy bulletproof embedded software
Retired package: Release invalid - Causes gcc compiler errors when using TARGET_GCC_FLAGS feature
Current section
Files
Jump to
Current section
Files
lib/nerves/artifact/resolvers/github_api.ex
defmodule Nerves.Artifact.Resolvers.GithubAPI do
@behaviour Nerves.Artifact.Resolver
@base_url "https://api.github.com/"
@required_opts [:username, :token, :tag]
alias Nerves.Utils
alias Nerves.Utils.HTTPClient
def get({org_proj, opts}) do
case validate_opts(opts) do
{:ok, opts} ->
fetch_artifact(org_proj, opts)
{:error, missing} ->
missing = Enum.join(missing, ", ")
artifact_name = opts[:artifact_name]
error = """
Skipping: #{artifact_name}
Required options missing: [#{missing}]
"""
{:error, error}
end
end
defp fetch_artifact(org_proj, opts) do
artifact_name = opts[:artifact_name]
{:ok, http_pid} = HTTPClient.start_link()
token = get_token(opts, artifact_name)
username = get_username(opts, artifact_name)
tag = get_tag(opts, artifact_name)
credentials = Base.encode64(username <> ":" <> token)
auth_header = {"Authorization", "Basic " <> credentials}
accept_header = {"Accept", "application/octet-stream"}
base_url = opts[:base_url] || @base_url
url = Path.join([base_url, "repos", org_proj, "releases", "tags", tag])
Nerves.Utils.Shell.info(" Downloading artifacts from #{url}")
url = URI.encode(url)
result =
with {:ok, data} <- HTTPClient.get(http_pid, url, headers: [auth_header], progress?: false),
%{"assets" => assets} <- Utils.json_decode(data),
{:ok, url} <- get_asset_url(assets, artifact_name),
{:ok, data} <- HTTPClient.get(http_pid, url, headers: [auth_header, accept_header]) do
{:ok, data}
end
Nerves.Utils.HTTPClient.stop(http_pid)
result
end
def validate_opts(opts) do
keys = Keyword.keys(opts)
case Enum.split_with(@required_opts, &(&1 in keys)) do
{_, [_ | _] = missing} -> {:error, missing}
_ -> {:ok, opts}
end
end
defp get_asset_url(assets, artifact_name) do
ret =
Enum.find(assets, fn %{"name" => name} ->
String.equivalent?(artifact_name, name)
end)
case ret do
nil -> {:error, "No artifact found"}
%{"url" => url} -> {:ok, url}
end
end
defp get_username(opts, artifact_name) do
case Keyword.get(opts, :username) do
nil ->
Mix.raise("""
GitHub username not set for artifact: #{artifact_name}.
Ensure that you have your GitHub username set correctly
in your environment. You might need to export an environmental
variable.
For example:
export GITHUB_USER=<your_username>
For correctly setting up your environment please see the documentation for the artifact you are
trying to download.
""")
username ->
username
end
end
defp get_token(opts, artifact_name) do
case Keyword.get(opts, :token) do
nil ->
Mix.raise("""
GitHub token not set for artifact: #{artifact_name}
Ensure that you have your GitHub token set correctly
in your environment. You might need to export an environmental
variable.
For example:
export GITHUB_TOKEN=<your_token>
For correctly setting up your environment please see the documentation for the artifact you are
trying to download.
""")
token ->
token
end
end
defp get_tag(opts, artifact_name) do
case Keyword.get(opts, :tag) do
nil ->
Mix.raise("""
GitHub release tag not set for artifact: #{artifact_name}.
Ensure that you have set the tag field in the artifact sites
configuration for this artifact.
For example:
{:github_api, "github_org/my_custom_system", username: System.get_env("GITHUB_USER"), token: System.get_env("GITHUB_TOKEN"), tag: @version}
""")
tag ->
tag
end
end
end