Packages

Base library to create AWS Lambda, Azure Functions or IBM Functions

Current section

Files

Jump to
faas_base lib mix tasks azure release.ex
Raw

lib/mix/tasks/azure/release.ex

defmodule Mix.Tasks.Azure.Release do
@moduledoc """
Create files to publish Azure Functions.
Run this task inside Docker image `elixir:1.10.4-slim`.
## How to build
```
$ mkdir -p _build
$ docker run -d -it --rm --name elx erintheblack/elixir-azure-functions-builder:1.10.4
$ docker cp lib elx:/tmp
$ docker cp mix.exs elx:/tmp
$ docker exec elx /bin/bash -c "mix deps.get; MIX_ENV=prod mix azure.release ${handle_module} ${method_name} 'get post'"
$ docker cp elx:/tmp/_azure ./_build
$ docker stop elx
```
"""
use Mix.Task
@build_dir "_azure"
@doc """
Create files to publish Azure Functions.
"""
@impl Mix.Task
def run([handler_module]) do
app_name = app_name()
bootstrap = bootstrap(app_name)
host_json = host_json(app_name)
local_setting_json = local_setting_json(handler_module)
env = Mix.env()
Mix.Shell.cmd("rm -f -R ./#{@build_dir}/*", &IO.puts/1)
Mix.Shell.cmd("mkdir -p ./#{@build_dir}", &IO.puts/1)
Mix.Shell.cmd("rm -f -R ./_build/#{env}/*", &IO.puts/1)
Mix.Shell.cmd("MIX_ENV=#{env} mix release --quiet", &IO.puts/1)
File.write("./_build/#{env}/rel/#{app_name}/bootstrap", bootstrap)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/bin/#{app_name}", &IO.puts/1)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/releases/*/elixir", &IO.puts/1)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/erts-*/bin/erl", &IO.puts/1)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/bootstrap", &IO.puts/1)
Mix.Shell.cmd("cp -a ./_build/#{env}/rel/#{app_name} ./#{@build_dir}/", &IO.puts/1)
File.write("./#{@build_dir}/host.json", host_json)
File.write("./#{@build_dir}/local.settings.json", local_setting_json)
end
def run([handler_module, method_name, method_types]) do
function_json = function_json(~w/#{method_types}/)
run([handler_module])
Mix.Shell.cmd("mkdir -p ./#{@build_dir}/#{method_name}", &IO.puts/1)
File.write("./#{@build_dir}/#{method_name}/function.json", function_json)
end
defp app_name do
Mix.Project.config() |> Keyword.get(:app) |> to_string
end
defp bootstrap(app_name) do
"""
#!/bin/sh
set -e
bin/#{app_name} start
"""
end
defp host_json(app_name) do
"""
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
},
"customHandler": {
"description": {
"defaultExecutablePath": "#{app_name}/bootstrap",
"workingDirectory": "#{app_name}",
"arguments": []
}
}
}
"""
end
defp local_setting_json(handler_module) do
"""
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "custom",
"_HANDLER": "#{handler_module}",
"LOG_LEVEL": "info"
}
}
"""
end
defp function_json(method_types) do
"""
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": #{method_types |> inspect}
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
"""
end
end