Skip to content

Commit

Permalink
Improve CI pipeline (open-api-spex#377)
Browse files Browse the repository at this point in the history
* Improve test matrix
* Run Dialyzer in CI
* Run in CI
* Only enforce formatting on latest elixir version

Co-authored-by: Luca Corti <luca.corti@dottori.it>
Co-authored-by: Luca Corti <luca@sibill.it>
  • Loading branch information
3 people authored May 23, 2022
1 parent fa684e9 commit cdb4461
Show file tree
Hide file tree
Showing 55 changed files with 305 additions and 253 deletions.
19 changes: 19 additions & 0 deletions .credo.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
%{
configs: [
%{
name: "default",
files: %{
included: ["lib/"],
excluded: []
},
plugins: [],
requires: [],
strict: true,
parse_timeout: 5000,
color: true,
checks: [
{Credo.Check.Consistency.ParameterPatternMatching, false}
]
}
]
}
72 changes: 48 additions & 24 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,59 @@ on:
branches: [master]

jobs:
build:
name: Build and test
runs-on: ubuntu-18.04
lint:
name: Lint (OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}})
runs-on: ubuntu-latest
strategy:
matrix:
elixir: [1.9, 1.12]
otp: [23.0]

otp: ['25']
elixir: ['1.13']
steps:
- uses: actions/checkout@v2
- name: Set up Elixir
uses: actions/setup-elixir@v1
- uses: erlef/setup-beam@v1
id: beam
with:
elixir-version: ${{ matrix.elixir }} # Define the elixir version [required]
otp-version: ${{ matrix.otp }} # Define the OTP version [required]
- name: Restore dependencies cache
otp-version: ${{matrix.otp}}
elixir-version: ${{matrix.elixir}}
- name: PLT cache
uses: actions/cache@v2
with:
key: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
restore-keys: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
path: |
priv/plts
- run: mix deps.get
- run: mix compile --warnings-as-errors
- run: mix format --check-formatted
- run: mix credo --strict --all
- run: mix dialyzer
test:
runs-on: ubuntu-latest
name: Test (OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}})
strategy:
matrix:
otp: ['22', '23', '24', '25']
elixir: ['1.10', '1.11', '1.12', '1.13']
exclude:
- {otp: '24', elixir: '1.10'}
- {otp: '25', elixir: '1.10'}
- {otp: '25', elixir: '1.11'}
- {otp: '25', elixir: '1.12'}
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
with:
otp-version: ${{matrix.otp}}
elixir-version: ${{matrix.elixir}}
- uses: actions/cache@v2
with:
key: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-build
restore-keys: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-build
path: |
deps
_build/test
key: ${{ runner.os }}-deps-${{ hashFiles('**/mix.lock', '**/config/*.exs') }}
restore-keys: ${{ runner.os }}-deps-
- name: Install and compile dependencies
run: MIX_ENV=test mix do deps.get, deps.compile
- name: Compile application
run: MIX_ENV=test mix compile --warnings-as-errors
- name: Check formatting
if: ${{ matrix.elixir == '1.12' }}
run: mix format --check-formatted
- name: Run tests
run: mix test
_build
- run: mix deps.get
- run: mix test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ open_api_spex-*.tar
.vscode/
.idea
*.iml

/priv/plts
32 changes: 0 additions & 32 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
import Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
Expand Down
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
use Mix.Config
import Config

config :logger, level: :info
2 changes: 1 addition & 1 deletion examples/phoenix_app/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ defmodule PhoenixApp.Mixfile do
[
{:open_api_spex, path: "../../"},
{:ecto, "~> 2.2"},
{:httpoison, "~> 1.7"},
{:sqlite_ecto2, "~> 2.4"},
{:phoenix, "~> 1.4"},
{:plug_cowboy, "~> 2.0"},
{:jason, "~> 1.0"},
{:httpoison, "~> 1.7"},
{:dialyxir, "1.0.0-rc.6", only: [:dev], runtime: false}
]
end
Expand Down
4 changes: 2 additions & 2 deletions lib/open_api_spex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ defmodule OpenApiSpex do
Operation2,
Reference,
Schema,
SchemaConsistency,
SchemaException,
SchemaResolver,
SchemaConsistency
SchemaResolver
}

alias OpenApiSpex.Cast.Error
Expand Down
2 changes: 2 additions & 0 deletions lib/open_api_spex/cast.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
defmodule OpenApiSpex.Cast do
@moduledoc "Cast and validate a value against an OpenApiSpex schema"

alias OpenApiSpex.{Reference, Schema}
alias OpenApiSpex.Reference

Expand Down
18 changes: 9 additions & 9 deletions lib/open_api_spex/cast/all_of.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ defmodule OpenApiSpex.Cast.AllOf do
{:ok, Enum.concat(acc, value)}

{:error, errors} ->
with {:ok, cleaned_ctx} <- reject_error_values(ctx, errors) do
case Cast.cast(cleaned_ctx) do
{:ok, cleaned_values} ->
new_ctx = put_in(ctx.schema.allOf, remaining)
new_ctx = update_in(new_ctx.value, fn values -> values -- cleaned_ctx.value end)
cast_all_of(new_ctx, Enum.concat(acc, cleaned_values))
end
with {:ok, cleaned_ctx} <- reject_error_values(ctx, errors),
{:ok, cleaned_values} <- Cast.cast(cleaned_ctx) do
new_ctx = put_in(ctx.schema.allOf, remaining)
new_ctx = update_in(new_ctx.value, fn values -> values -- cleaned_ctx.value end)
cast_all_of(new_ctx, Enum.concat(acc, cleaned_values))
else
_ -> Cast.error(ctx, {:all_of, to_string(schema.title || schema.type)})
end
Expand All @@ -48,8 +46,10 @@ defmodule OpenApiSpex.Cast.AllOf do
cast_all_of(new_ctx, acc)

{:ok, value} ->
# allOf definitions with primitives are a little bit strange..., we just return the cast for the first Schema,
# but validate the values against every other schema as well, since the value must be compatible with all Schemas
# allOf definitions with primitives are a little bit strange.
# we just return the cast for the first Schema, but validate
# the values against every other schema as well, since the value
# must be compatible with all Schemas
cast_all_of(new_ctx, acc || value)

{:error, _} ->
Expand Down
14 changes: 9 additions & 5 deletions lib/open_api_spex/cast/discriminator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,15 @@ defmodule OpenApiSpex.Cast.Discriminator do
do: {locate_schemas(schemas, ctx.schemas), Cast.cast(ctx)}

defp find_discriminator_schema(discriminator, mappings = %{}, schemas) do
with {:ok, "#/components/schemas/" <> name} <- Map.fetch(mappings, discriminator) do
find_discriminator_schema(name, nil, schemas)
else
{:ok, name} -> find_discriminator_schema(name, nil, schemas)
:error -> find_discriminator_schema(discriminator, nil, schemas)
case Map.fetch(mappings, discriminator) do
{:ok, "#/components/schemas/" <> name} ->
find_discriminator_schema(name, nil, schemas)

{:ok, name} ->
find_discriminator_schema(name, nil, schemas)

:error ->
find_discriminator_schema(discriminator, nil, schemas)
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/open_api_spex/cast/error.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
defmodule OpenApiSpex.Cast.Error do
@moduledoc "OpenApiSpex Cast Error"

alias OpenApiSpex.TermType

@type all_of_error :: {:all_of, [String.t()]}
Expand Down
5 changes: 3 additions & 2 deletions lib/open_api_spex/cast/number.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ defmodule OpenApiSpex.Cast.Number do
@moduledoc false
alias OpenApiSpex.Cast

# credo:disable-for-next-line
# TODO We need a way to distinguish numbers in (JSON) body vs in request parameters
# so we can reject strings values for properties of `type: :number`
@spec cast(ctx :: Cast.t()) :: {:ok, Cast.t()} | Cast.Error.t()
def cast(%{value: value} = ctx) when is_number(value) do
case cast_number(ctx) do
Expand All @@ -10,8 +13,6 @@ defmodule OpenApiSpex.Cast.Number do
end
end

# TODO We need a way to distinguish numbers in (JSON) body vs in request parameters
# so we can reject strings values for properties of `type: :number`
def cast(%{value: value} = ctx) when is_binary(value) do
case Float.parse(value) do
{value, ""} -> cast(%{ctx | value: value})
Expand Down
1 change: 1 addition & 0 deletions lib/open_api_spex/cast/string.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ defmodule OpenApiSpex.Cast.String do
?e,
?f
]
# credo:disable-for-next-line
def cast(%{
value:
<<a1, a2, a3, a4, a5, a6, a7, a8, ?-, b1, b2, b3, b4, ?-, c1, c2, c3, c4, ?-, d1, d2, d3,
Expand Down
2 changes: 1 addition & 1 deletion lib/open_api_spex/cast_parameters.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule OpenApiSpex.CastParameters do
@moduledoc false
alias OpenApiSpex.{Cast, Operation, Parameter, Schema, Reference, Components}
alias OpenApiSpex.{Cast, Components, Operation, Parameter, Reference, Schema}
alias OpenApiSpex.Cast.Error
alias Plug.Conn

Expand Down
16 changes: 8 additions & 8 deletions lib/open_api_spex/components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ defmodule OpenApiSpex.Components do
Defines the `OpenApiSpex.Components.t` type.
"""
alias OpenApiSpex.{
Schema,
Reference,
Response,
Parameter,
Callback,
Components,
Example,
RequestBody,
Header,
SecurityScheme,
Link,
Callback,
Components
Parameter,
Reference,
RequestBody,
Response,
Schema,
SecurityScheme
}

defstruct [
Expand Down
Loading

0 comments on commit cdb4461

Please sign in to comment.