Skip to content

Commit dc5b788

Browse files
committed
Init release
0 parents  commit dc5b788

35 files changed

+3118
-0
lines changed

.credo.exs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
%{
2+
configs: [
3+
%{
4+
name: "default",
5+
files: %{
6+
included: ["lib/", "src/"],
7+
excluded: []
8+
},
9+
plugins: [],
10+
requires: [],
11+
strict: false,
12+
parse_timeout: 5000,
13+
color: true,
14+
checks: %{
15+
disabled: [
16+
# Styler Rewrites
17+
#
18+
# The following rules are automatically rewritten by Styler and so disabled here to save time
19+
# Some of the rules have `priority: :high`, meaning Credo runs them unless we explicitly disable them
20+
# (removing them from this file wouldn't be enough, the `false` is required)
21+
#
22+
# Some rules have a comment before them explaining ways Styler deviates from the Credo rule.
23+
#
24+
# always expands `A.{B, C}`
25+
# {Credo.Check.Consistency.MultiAliasImportRequireUse, false},
26+
# including `case`, `fn` and `with` statements
27+
{Credo.Check.Consistency.ParameterPatternMatching, false},
28+
# Styler implements this rule with a depth of 3 and minimum repetition of 2
29+
{Credo.Check.Design.AliasUsage, false},
30+
{Credo.Check.Readability.AliasOrder, false},
31+
{Credo.Check.Readability.BlockPipe, false},
32+
# goes further than formatter - fixes bad underscores, eg: `100_00` -> `10_000`
33+
{Credo.Check.Readability.LargeNumbers, false},
34+
# adds `@moduledoc false`
35+
{Credo.Check.Readability.ModuleDoc, false},
36+
{Credo.Check.Readability.MultiAlias, false},
37+
{Credo.Check.Readability.OneArityFunctionInPipe, false},
38+
# removes parens
39+
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, false},
40+
{Credo.Check.Readability.PipeIntoAnonymousFunctions, false},
41+
{Credo.Check.Readability.PreferImplicitTry, false},
42+
{Credo.Check.Readability.SinglePipe, false},
43+
# **potentially breaks compilation** - see **Troubleshooting** section below
44+
{Credo.Check.Readability.StrictModuleLayout, false},
45+
{Credo.Check.Readability.StringSigils, false},
46+
{Credo.Check.Readability.UnnecessaryAliasExpansion, false},
47+
{Credo.Check.Readability.WithSingleClause, false},
48+
{Credo.Check.Refactor.CaseTrivialMatches, false},
49+
{Credo.Check.Refactor.CondStatements, false},
50+
# in pipes only
51+
{Credo.Check.Refactor.FilterCount, false},
52+
# in pipes only
53+
{Credo.Check.Refactor.MapInto, false},
54+
# in pipes only
55+
{Credo.Check.Refactor.MapJoin, false},
56+
# {Credo.Check.Refactor.NegatedConditionsInUnless, false},
57+
# {Credo.Check.Refactor.NegatedConditionsWithElse, false},
58+
# allows ecto's `from
59+
{Credo.Check.Refactor.PipeChainStart, false},
60+
{Credo.Check.Refactor.RedundantWithClauseResult, false},
61+
{Credo.Check.Refactor.UnlessWithElse, false},
62+
{Credo.Check.Refactor.WithClauses, false},
63+
64+
# custom ext_fit rules
65+
{Credo.Check.Refactor.Nesting, false},
66+
{Credo.Check.Refactor.CyclomaticComplexity, false},
67+
{Credo.Check.Design.TagFIXME, false},
68+
{Credo.Check.Design.TagTODO, false}
69+
]
70+
}
71+
}
72+
]
73+
}

.dialyzer_ignore.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

.envrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dotenv
2+
dotenv_if_exists .env.private

.formatter.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Used by "mix format"
2+
[
3+
line_length: 99,
4+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
5+
]
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
name: Setup Elixir Project
2+
description: Checks out the code, configures Elixir, fetches dependencies, and manages build caching.
3+
inputs:
4+
elixir-version:
5+
required: true
6+
type: string
7+
description: Elixir version to set up
8+
otp-version:
9+
required: true
10+
type: string
11+
description: OTP version to set up
12+
#################################################################
13+
# Everything below this line is optional.
14+
#
15+
# It's designed to make compiling a reasonably standard Elixir
16+
# codebase "just work," though there may be speed gains to be had
17+
# by tweaking these flags.
18+
#################################################################
19+
build-deps:
20+
required: false
21+
type: boolean
22+
default: true
23+
description: True if we should compile dependencies
24+
build-app:
25+
required: false
26+
type: boolean
27+
default: true
28+
description: True if we should compile the application itself
29+
build-flags:
30+
required: false
31+
type: string
32+
default: '--all-warnings'
33+
description: Flags to pass to mix compile
34+
install-rebar:
35+
required: false
36+
type: boolean
37+
default: true
38+
description: By default, we will install Rebar (mix local.rebar --force).
39+
install-hex:
40+
required: false
41+
type: boolean
42+
default: true
43+
description: By default, we will install Hex (mix local.hex --force).
44+
cache-key:
45+
required: false
46+
type: string
47+
default: 'v1'
48+
description: If you need to reset the cache for some reason, you can change this key.
49+
outputs:
50+
otp-version:
51+
description: "Exact OTP version selected by the BEAM setup step"
52+
value: ${{ steps.beam.outputs.otp-version }}
53+
elixir-version:
54+
description: "Exact Elixir version selected by the BEAM setup step"
55+
value: ${{ steps.beam.outputs.elixir-version }}
56+
runs:
57+
using: "composite"
58+
steps:
59+
- name: Setup elixir
60+
uses: erlef/setup-beam@v1
61+
id: beam
62+
with:
63+
elixir-version: ${{ inputs.elixir-version }}
64+
otp-version: ${{ inputs.otp-version }}
65+
66+
- name: Get deps cache
67+
uses: actions/cache@v2
68+
with:
69+
path: deps/
70+
key: deps-${{ inputs.cache-key }}-${{ runner.os }}-${{ hashFiles('**/mix.lock') }}
71+
restore-keys: |
72+
deps-${{ inputs.cache-key }}-${{ runner.os }}-
73+
74+
- name: Get build cache
75+
uses: actions/cache@v2
76+
id: build-cache
77+
with:
78+
path: _build/${{env.MIX_ENV}}/
79+
key: build-${{ inputs.cache-key }}-${{ runner.os }}-${{ inputs.otp-version }}-${{ inputs.elixir-version }}-${{ env.MIX_ENV }}-${{ hashFiles('**/mix.lock') }}
80+
restore-keys: |
81+
build-${{ inputs.cache-key }}-${{ runner.os }}-${{ inputs.otp-version }}-${{ inputs.elixir-version }}-${{ env.MIX_ENV }}-
82+
83+
- name: Get Hex cache
84+
uses: actions/cache@v2
85+
id: hex-cache
86+
with:
87+
path: ~/.hex
88+
key: build-${{ runner.os }}-${{ inputs.otp-version }}-${{ inputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}
89+
restore-keys: |
90+
build-${{ runner.os }}-${{ inputs.otp-version }}-${{ inputs.elixir-version }}-
91+
92+
# In my experience, I have issues with incremental builds maybe 1 in 100
93+
# times that are fixed by doing a full recompile.
94+
# In order to not waste dev time on such trivial issues (while also reaping
95+
# the time savings of incremental builds for *most* day-to-day development),
96+
# I force a full recompile only on builds that we retry.
97+
- name: Clean to rule out incremental build as a source of flakiness
98+
if: github.run_attempt != '1'
99+
run: |
100+
mix deps.clean --all
101+
mix clean
102+
shell: sh
103+
104+
- name: Install Rebar
105+
run: mix local.rebar --force
106+
shell: sh
107+
if: inputs.install-rebar == 'true'
108+
109+
- name: Install Hex
110+
run: mix local.hex --force
111+
shell: sh
112+
if: inputs.install-hex == 'true'
113+
114+
- name: Install Dependencies
115+
run: mix deps.get
116+
shell: sh
117+
118+
# Normally we'd use `mix deps.compile` here, however that incurs a large
119+
# performance penalty when the dependencies are already fully compiled:
120+
# https://elixirforum.com/t/github-action-cache-elixir-always-recompiles-dependencies-elixir-1-13-3/45994/12
121+
#
122+
# Accoring to Jose Valim at the above link `mix loadpaths` will check and
123+
# compile missing dependencies
124+
- name: Compile Dependencies
125+
run: mix loadpaths
126+
shell: sh
127+
if: inputs.build-deps == 'true'
128+
129+
- name: Compile Application
130+
run: mix compile ${{ inputs.build-flags }}
131+
shell: sh
132+
if: inputs.build-app == 'true'

.github/dependabot.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: mix
4+
directory: "/"
5+
schedule:
6+
interval: weekly
7+
time: "12:00"
8+
open-pull-requests-limit: 3
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- '*'
10+
11+
jobs:
12+
build:
13+
name: Build and test
14+
runs-on: ubuntu-latest
15+
env:
16+
MIX_ENV: test
17+
strategy:
18+
matrix:
19+
elixir: ["1.16.2"]
20+
otp: ["25.3.2"]
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v2
25+
26+
- name: Setup Elixir Project
27+
uses: ./.github/actions/elixir-setup
28+
with:
29+
elixir-version: ${{ matrix.elixir }}
30+
otp-version: ${{ matrix.otp }}
31+
build-flags: --all-warnings --warnings-as-errors
32+
33+
- name: Run Tests
34+
run: mix coveralls.json --warnings-as-errors
35+
if: always()

.github/workflows/elixir-dialyzer.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Elixir Type Linting
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- '*'
10+
11+
jobs:
12+
build:
13+
name: Run Dialyzer
14+
runs-on: ubuntu-latest
15+
env:
16+
MIX_ENV: dev
17+
strategy:
18+
matrix:
19+
elixir: ["1.16.2"]
20+
otp: ["25.3.2"]
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v2
25+
26+
- name: Setup Elixir Project
27+
uses: ./.github/actions/elixir-setup
28+
id: beam
29+
with:
30+
elixir-version: ${{ matrix.elixir }}
31+
otp-version: ${{ matrix.otp }}
32+
build-app: false
33+
34+
# Don't cache PLTs based on mix.lock hash, as Dialyzer can incrementally update even old ones
35+
# Cache key based on Elixir & Erlang version (also useful when running in matrix)
36+
- name: Restore PLT cache
37+
uses: actions/cache@v3
38+
id: plt_cache
39+
with:
40+
key: plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}-${{ hashFiles('**/*.ex') }}
41+
restore-keys: |
42+
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}-${{ hashFiles('**/*.ex') }}
43+
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}-
44+
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-
45+
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-
46+
path: priv/plts
47+
48+
# Create PLTs if no cache was found.
49+
# Always rebuild PLT when a job is retried
50+
# (If they were cached at all, they'll be updated when we run mix dialyzer with no flags.)
51+
- name: Create PLTs
52+
if: steps.plt_cache.outputs.cache-hit != 'true' || github.run_attempt != '1'
53+
run: mix dialyzer --plt
54+
55+
- name: Run Dialyzer
56+
run: mix dialyzer --format github
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Elixir Quality Checks
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- '*'
10+
11+
jobs:
12+
quality_checks:
13+
name: Formatting, and Unused Deps
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
elixir: ["1.16.2"]
18+
otp: ["25.3.2"]
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v2
23+
24+
- name: Setup Elixir Project
25+
uses: ./.github/actions/elixir-setup
26+
with:
27+
elixir-version: ${{ matrix.elixir }}
28+
otp-version: ${{ matrix.otp }}
29+
build-app: false
30+
31+
- name: Check for unused deps
32+
run: mix deps.unlock --check-unused
33+
- name: Check code formatting
34+
run: mix format --check-formatted
35+
# Check formatting even if there were unused deps so that
36+
# we give devs as much feedback as possible & save some time.
37+
if: always()
38+
- name: Run Credo
39+
run: mix credo suggest --min-priority=normal
40+
# Run Credo even if formatting or the unused deps check failed
41+
if: always()
42+
# - name: Check for compile-time dependencies
43+
# run: mix xref graph --label compile-connected --fail-above 0
44+
# if: always()
45+
# - name: Check for security vulnerabilities in Phoenix project
46+
# run: mix sobelow
47+
# if: always()

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# Ignore .fetch files in case you like to edit your project deps locally.
14+
/.fetch
15+
16+
# If the VM crashes, it generates a dump, let's ignore it too.
17+
erl_crash.dump
18+
19+
# Also ignore archive artifacts (built via "mix archive.build").
20+
*.ez
21+
22+
# Ignore package tarball (built via "mix hex.build").
23+
nimrag-*.tar
24+
25+
# Temporary files, for example, from tests.
26+
/tmp/
27+
28+
priv/plts

0 commit comments

Comments
 (0)