Skip to content

Commit

Permalink
Update tests for Elixir 1.18.1
Browse files Browse the repository at this point in the history
  • Loading branch information
NickNeck committed Jan 2, 2025
1 parent 8dfaab7 commit ce4af7a
Show file tree
Hide file tree
Showing 27 changed files with 1,937 additions and 37 deletions.
338 changes: 338 additions & 0 deletions .gha/default.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
defmodule GitHubActions.Default do
use GitHubActions.Workflow

def workflow do
[
name: "CI",
env: [
GITHUB_TOKEN: ~e[secrets.GITHUB_TOKEN]
],
on: ~w(pull_request push),
jobs: [
linux: job(:linux),
windows: job(:windows),
macos: job(:macos)
]
]
end

defp elixir_version do
elixir = Config.get(:elixir)
if elixir, do: "~> #{Version.minor(elixir)}", else: Project.elixir()
end

defp otp_version, do: "> 21.0.0"

defp matrix do
Versions.matrix(
elixir: elixir_version(),
otp: otp_version()
)
end

defp job(:linux = os) do
job(os,
name: """
Test on #{Config.get([os, :name])} (\
Elixir #{~e[matrix.elixir]}, \
OTP #{~e[matrix.otp]})\
""",
runs_on: Config.get([os, :runs_on]),
strategy: [matrix: matrix()],
steps: [
checkout(),
setup_elixir(os),
restore(:deps),
restore(:_build),
restore(:dialyxir),
get_deps(),
compile_deps(os),
compile(os),
check_unused_deps(),
check_code_format(),
lint_code(),
run_tests(os),
run_coverage(os),
dialyxir()
]
)
end

defp job(:windows = os) do
job(os,
name: "Test on #{Config.get([os, :name])}",
runs_on: Config.get([os, :runs_on]),
steps: [
checkout(),
setup_elixir(os),
get_deps(),
compile_deps(os),
compile(os),
run_tests(os),
run_coverage(os)
]
)
end

defp job(:macos = os) do
job(os,
name: "Test on #{Config.get([os, :name])}",
runs_on: Config.get([os, :runs_on]),
steps: [
checkout(),
setup_elixir(os),
install_hex(),
install_rebar(),
restore(:deps),
restore(:_build),
get_deps(),
compile_deps(os),
compile(os),
run_tests(os),
run_coverage(os)
]
)
end

defp job(os, config) do
case member?(:jobs, os) do
true -> config
false -> :skip
end
end

defp checkout do
[
name: "Checkout",
uses: "actions/checkout@v4"
]
end

defp setup_elixir(:linux) do
[
name: "Setup Elixir",
id: "setup-beam",
uses: "erlef/setup-beam@v1",
with: [
elixir_version: ~e[matrix.elixir],
otp_version: ~e[matrix.otp]
]
]
end

defp setup_elixir(:macos) do
[
name: "Setup Elixir",
id: "setup-beam",
run: "brew install elixir"
]
end

defp setup_elixir(:windows) do
[
name: "Setup Elixir",
id: "setup-beam",
uses: "erlef/setup-beam@v1",
with: [
elixir_version: Versions.latest(:elixir),
otp_version: Versions.latest(:otp)
]
]
end

defp install_hex do
[
name: "Install hex",
run: mix(:local, :hex, force: true)
]
end

defp install_rebar do
[
name: "Install rebar",
run: mix(:local, :rebar, force: true)
]
end

defp restore(:dialyxir) do
case Project.has_dep?(:dialyxir) and Config.get([:steps, :dialyxir]) do
false ->
:skip

true ->
case Project.fetch([:dialyzer, :plt_file]) do
:error ->
:skip

{:ok, {_, file}} ->
file |> Path.dirname() |> restore(if: latest_version(true))
end
end
end

defp restore(path, opts \\ []) do
case Config.fetch!([:steps, :refresh]) do
false ->
:skip

true ->
{opt_if, opts} = Keyword.pop(opts, :if)
opt_if = if opt_if, do: [if: opt_if], else: []

Keyword.merge(
[name: "Restore #{path}"] ++
opt_if ++
[
uses: "actions/cache@v4",
with: [
path: path,
key: key(path)
]
],
opts
)
end
end

defp get_deps do
[
name: "Get dependencies",
run: mix(:deps, :get)
]
end

defp compile_deps(os) do
[
name: "Compile dependencies",
run: mix(:deps, :compile, env: :test, os: os)
]
end

defp compile(os) do
[
name: "Compile project",
run: mix(:compile, warnings_as_errors: true, env: :test, os: os)
]
end

defp check_unused_deps do
case Config.get(:check_unused_deps, true) do
false ->
:skip

true ->
[
name: "Check unused dependencies",
if: latest_version(true),
run: mix(:deps, :unlock, check_unused: true)
]
end
end

defp check_code_format do
case Config.get(:check_code_format, true) do
false ->
:skip

true ->
[
name: "Check code format",
if: latest_version(true),
run: mix(:format, check_formatted: true)
]
end
end

defp lint_code do
case Project.has_dep?(:credo) do
false ->
:skip

true ->
[
name: "Lint code",
if: latest_version(true),
run: mix(:credo, strict: true)
]
end
end

defp run_tests(:windows) do
[
name: "Run tests",
run: mix(:test)
]
end

defp run_tests(_nix) do
case Project.has_dep?(:excoveralls) do
true ->
[
name: "Run tests",
if: latest_version(false),
run: mix(:test)
]

false ->
[
name: "Run tests",
run: mix(:test)
]
end
end

defp run_coverage(:windows), do: :skip

defp run_coverage(_nix) do
case Project.has_dep?(:excoveralls) do
true ->
[
name: "Run tests with coverage",
if: latest_version(true),
run: mix(:coveralls, Config.get([:steps, :coveralls]))
]

false ->
:skip
end
end

defp dialyxir do
case Project.has_dep?(:dialyxir) do
false ->
:skip

true ->
[
name: "Static code analysis",
if: latest_version(true),
run: mix(:dialyzer, force_check: true, format: "github")
]
end
end

defp key(key) do
os = ~e[runner.os]
elixir = ~e[matrix.elixir]
otp = ~e[matrix.otp]
setup_beam_version = ~e{steps.setup-beam.outputs.setup-beam-version}
lock = ~e[hashFiles(format('{0}{1}', github.workspace, '/mix.lock'))]
"#{key}-#{os}-#{elixir}-#{otp}-#{lock}-#{setup_beam_version}"
end

defp latest_version(true) do
~e"""
matrix.elixir == '#{Versions.latest(:elixir)}' && \
matrix.otp == '#{Versions.latest(:otp)}'\
"""
end

defp latest_version(false) do
~e"""
!(matrix.elixir == '#{Versions.latest(:elixir)}' && \
matrix.otp == '#{Versions.latest(:otp)}')\
"""
end

defp member?(key, value), do: key |> Config.get() |> Enum.member?(value)
end
Loading

0 comments on commit ce4af7a

Please sign in to comment.