04f0bbb05b
Takes in GitLab push webhook events instead of normal triggers
84 lines
2.4 KiB
Elixir
84 lines
2.4 KiB
Elixir
defmodule GitLabPushTriggerer do
|
|
require Logger
|
|
|
|
@split_char ";"
|
|
|
|
@doc """
|
|
Get all matching environment variables and their values. Returns a map where keys are the transformed
|
|
paths and values are the given script paths.
|
|
|
|
## Examples
|
|
|
|
In these examples, sample env is given as argument. If no argument is given, system env is used.
|
|
|
|
iex> GitLabPushTriggerer.get_envs(%{"GLPT_FOO" => "master;./test.sh"})
|
|
%{"foo" => {"master", "./test.sh"}}
|
|
|
|
iex> GitLabPushTriggerer.get_envs(%{})
|
|
%{}
|
|
|
|
iex> GitLabPushTriggerer.get_envs(%{"WRONG_FORMAT" => "no", "GLPT_BAR_" => "um;baz", "GLPT_" => "no", "GLPT_GO_WILD" => "jeffum;/bin/true"})
|
|
%{"bar-" => {"um", "baz"}, "go-wild" => {"jeffum", "/bin/true"}}
|
|
"""
|
|
@spec get_envs(%{optional(String.t()) => String.t()}) :: map
|
|
def get_envs(envs \\ nil) do
|
|
envs = envs || System.get_env()
|
|
|
|
envs
|
|
|> Map.keys()
|
|
|> Enum.reduce(%{}, fn
|
|
"GLPT_" <> rest = key, acc when rest != "" ->
|
|
path = transform_path(rest)
|
|
[branch | rest] = String.split(envs[key], @split_char)
|
|
Map.put(acc, path, {branch, Enum.join(rest, @split_char)})
|
|
|
|
_, acc ->
|
|
acc
|
|
end)
|
|
end
|
|
|
|
@doc """
|
|
Transform a given path from environment variable style to endpoint style. That is, downcase it and
|
|
replace underscores with dashes.
|
|
|
|
## Examples
|
|
|
|
iex> GitLabPushTriggerer.transform_path("YKSI_KAKSI")
|
|
"yksi-kaksi"
|
|
|
|
iex> GitLabPushTriggerer.transform_path("FOO")
|
|
"foo"
|
|
|
|
iex> GitLabPushTriggerer.transform_path("ÄNKYRÄ_KÖNKYRÄ_")
|
|
"änkyrä-könkyrä-"
|
|
"""
|
|
@spec transform_path(String.t()) :: String.t()
|
|
def transform_path(path) when is_binary(path) do
|
|
String.split(path, "_")
|
|
|> Enum.map(&String.downcase/1)
|
|
|> Enum.join("-")
|
|
end
|
|
|
|
@doc """
|
|
Run given script or return an error.
|
|
"""
|
|
@spec run(String.t()) :: :ok | {:error, atom}
|
|
def run(script) do
|
|
runner = fn script ->
|
|
try do
|
|
{output, status} = System.cmd("sh", ["-c", script])
|
|
Logger.debug("Executed #{script} with return status #{status}. Output:\n\n#{output}")
|
|
rescue
|
|
err -> Logger.error("#{script} execution failed with: #{inspect(err)}")
|
|
end
|
|
end
|
|
|
|
if File.exists?(script) do
|
|
{:ok, pid} = Task.start(fn -> runner.(script) end)
|
|
Logger.debug("Started task #{script} with pid #{inspect(pid)}")
|
|
:ok
|
|
else
|
|
{:error, :file_not_found}
|
|
end
|
|
end
|
|
end
|