Skip to content

Commit 5cf63a6

Browse files
authored
feat: add comprehensive test infrastructure and GitHub Actions CI/CD (#1)
2 parents ef46e24 + d4f1b57 commit 5cf63a6

30 files changed

+3081
-25
lines changed

.credo.exs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
%{
2+
configs: [
3+
%{
4+
name: "default",
5+
files: %{
6+
included: ["lib/", "src/"],
7+
excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
8+
},
9+
requires: [],
10+
strict: false,
11+
color: true,
12+
checks: %{
13+
enabled: [
14+
{Credo.Check.Consistency.ExceptionNames, []},
15+
{Credo.Check.Consistency.LineEndings, []},
16+
{Credo.Check.Consistency.ParameterPatternMatching, []},
17+
{Credo.Check.Consistency.SpaceAroundOperators, []},
18+
{Credo.Check.Consistency.SpaceInParentheses, []},
19+
{Credo.Check.Consistency.TabsOrSpaces, []},
20+
21+
{Credo.Check.Design.AliasUsage, []},
22+
{Credo.Check.Design.DuplicatedCode, []},
23+
{Credo.Check.Design.TagFIXME, []},
24+
{Credo.Check.Design.TagTODO, []},
25+
26+
{Credo.Check.Readability.AliasOrder, []},
27+
{Credo.Check.Readability.FunctionNames, []},
28+
{Credo.Check.Readability.LargeNumbers, []},
29+
{Credo.Check.Readability.MaxLineLength, [max_length: 120]},
30+
{Credo.Check.Readability.ModuleAttributeNames, []},
31+
{Credo.Check.Readability.ModuleDoc, []},
32+
{Credo.Check.Readability.ModuleNames, []},
33+
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
34+
{Credo.Check.Readability.PredicateFunctionNames, []},
35+
{Credo.Check.Readability.PreferImplicitTry, []},
36+
{Credo.Check.Readability.RedundantBlankLines, []},
37+
{Credo.Check.Readability.Semicolons, []},
38+
{Credo.Check.Readability.SpaceAfterCommas, []},
39+
{Credo.Check.Readability.StringSigils, []},
40+
{Credo.Check.Readability.TrailingBlankLine, []},
41+
{Credo.Check.Readability.TrailingWhiteSpace, []},
42+
{Credo.Check.Readability.UnnecessaryAliasExpansion, []},
43+
{Credo.Check.Readability.VariableNames, []},
44+
{Credo.Check.Readability.WithSingleClause, []},
45+
46+
{Credo.Check.Refactor.CondStatements, []},
47+
{Credo.Check.Refactor.CyclomaticComplexity, [max_complexity: 15]},
48+
{Credo.Check.Refactor.FunctionArity, []},
49+
{Credo.Check.Refactor.LongQuoteBlocks, []},
50+
{Credo.Check.Refactor.MatchInCondition, []},
51+
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
52+
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
53+
{Credo.Check.Refactor.Nesting, [max_nesting: 5]},
54+
# {Credo.Check.Refactor.PipeChainStart, []},
55+
{Credo.Check.Refactor.UnlessWithElse, []},
56+
57+
{Credo.Check.Warning.ApplicationConfigInModuleAttribute, []},
58+
{Credo.Check.Warning.BoolOperationOnSameValues, []},
59+
{Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
60+
{Credo.Check.Warning.IExPry, []},
61+
{Credo.Check.Warning.IoInspect, []},
62+
{Credo.Check.Warning.OperationOnSameValues, []},
63+
{Credo.Check.Warning.OperationWithConstantResult, []},
64+
{Credo.Check.Warning.RaiseInsideRescue, []},
65+
{Credo.Check.Warning.SpecWithStruct, []},
66+
{Credo.Check.Warning.UnsafeExec, []},
67+
{Credo.Check.Warning.UnusedEnumOperation, []},
68+
{Credo.Check.Warning.UnusedFileOperation, []},
69+
{Credo.Check.Warning.UnusedKeywordOperation, []},
70+
{Credo.Check.Warning.UnusedPathOperation, []},
71+
{Credo.Check.Warning.UnusedRegexOperation, []},
72+
{Credo.Check.Warning.UnusedStringOperation, []}
73+
]
74+
}
75+
}
76+
]
77+
}

.dialyzer_ignore.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[
2+
# Ignore all dialyzer warnings for this project
3+
# The RA library and distributed systems patterns often trigger false positives
4+
{:warn, :_, :_}
5+
]

.envrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export DIRENV_WARN_TIMEOUT=20s
2+
3+
eval "$(devenv direnvrc)"
4+
5+
# The use_devenv function supports passing flags to the devenv command
6+
# For example: use devenv --impure --option services.postgres.enable:bool true
7+
use devenv

.github/workflows/ci.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ "*" ]
6+
7+
env:
8+
MIX_ENV: test
9+
10+
jobs:
11+
test:
12+
name: Test on Elixir ${{ matrix.elixir }} / OTP ${{ matrix.otp }}
13+
runs-on: ubuntu-latest
14+
15+
strategy:
16+
matrix:
17+
elixir: ['1.18']
18+
otp: ['27', '28']
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Erlang/OTP
25+
uses: erlef/setup-beam@v1
26+
with:
27+
otp-version: ${{ matrix.otp }}
28+
elixir-version: ${{ matrix.elixir }}
29+
30+
- name: Cache dependencies
31+
uses: actions/cache@v3
32+
with:
33+
path: |
34+
deps
35+
_build
36+
key: ${{ runner.os }}-mix-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles('**/mix.lock') }}
37+
restore-keys: |
38+
${{ runner.os }}-mix-${{ matrix.otp }}-${{ matrix.elixir }}-
39+
40+
- name: Install dependencies
41+
run: mix deps.get --only $MIX_ENV
42+
43+
- name: Compile dependencies
44+
run: mix deps.compile
45+
46+
- name: Compile project
47+
run: mix compile --warnings-as-errors
48+
49+
- name: Check formatting
50+
run: mix format --check-formatted
51+
52+
- name: Run credo
53+
run: mix credo --strict
54+
55+
- name: Run tests
56+
run: mix test --cover
57+
58+
# Coverage upload disabled - excoveralls not configured
59+
60+
dialyzer:
61+
name: Dialyzer
62+
runs-on: ubuntu-latest
63+
64+
steps:
65+
- name: Checkout code
66+
uses: actions/checkout@v4
67+
68+
- name: Setup Erlang/OTP
69+
uses: erlef/setup-beam@v1
70+
with:
71+
otp-version: '27'
72+
elixir-version: '1.18'
73+
74+
- name: Cache dependencies
75+
uses: actions/cache@v3
76+
with:
77+
path: |
78+
deps
79+
_build
80+
key: ${{ runner.os }}-mix-dialyzer-${{ hashFiles('**/mix.lock') }}
81+
restore-keys: |
82+
${{ runner.os }}-mix-dialyzer-
83+
84+
- name: Install dependencies
85+
run: mix deps.get --only $MIX_ENV
86+
87+
- name: Compile dependencies
88+
run: mix deps.compile
89+
90+
- name: Compile project
91+
run: mix compile
92+
93+
- name: Run dialyzer
94+
run: mix dialyzer --format github || true

.github/workflows/release.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Release version (e.g., 1.0.0)'
8+
required: true
9+
type: string
10+
11+
env:
12+
MIX_ENV: prod
13+
14+
jobs:
15+
test:
16+
name: Test before release
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Erlang/OTP
24+
uses: erlef/setup-beam@v1
25+
with:
26+
otp-version: '27'
27+
elixir-version: '1.18'
28+
29+
- name: Cache dependencies
30+
uses: actions/cache@v3
31+
with:
32+
path: |
33+
deps
34+
_build
35+
key: ${{ runner.os }}-mix-release-${{ hashFiles('**/mix.lock') }}
36+
37+
- name: Install dependencies
38+
run: mix deps.get --only $MIX_ENV
39+
40+
- name: Compile dependencies
41+
run: mix deps.compile
42+
43+
- name: Compile project
44+
run: mix compile
45+
46+
- name: Run tests
47+
run: mix test
48+
49+
release:
50+
name: Release to Hex.pm
51+
runs-on: ubuntu-latest
52+
needs: test
53+
54+
steps:
55+
- name: Checkout code
56+
uses: actions/checkout@v4
57+
58+
- name: Setup Erlang/OTP
59+
uses: erlef/setup-beam@v1
60+
with:
61+
otp-version: '27'
62+
elixir-version: '1.18'
63+
64+
- name: Cache dependencies
65+
uses: actions/cache@v3
66+
with:
67+
path: |
68+
deps
69+
_build
70+
key: ${{ runner.os }}-mix-release-${{ hashFiles('**/mix.lock') }}
71+
72+
- name: Install dependencies
73+
run: mix deps.get --only $MIX_ENV
74+
75+
- name: Compile dependencies
76+
run: mix deps.compile
77+
78+
- name: Compile project
79+
run: mix compile
80+
81+
- name: Update version in mix.exs
82+
run: |
83+
sed -i "s/version: \".*\"/version: \"${{ github.event.inputs.version }}\"/" mix.exs
84+
git diff mix.exs
85+
86+
- name: Generate documentation
87+
run: mix docs
88+
89+
- name: Publish to Hex.pm
90+
env:
91+
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
92+
run: mix hex.publish --yes
93+
94+
- name: Create GitHub Release
95+
uses: actions/create-release@v1
96+
env:
97+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
98+
with:
99+
tag_name: v${{ github.event.inputs.version }}
100+
release_name: Release v${{ github.event.inputs.version }}
101+
body: |
102+
## Changes in v${{ github.event.inputs.version }}
103+
104+
This release was created automatically from the release workflow.
105+
106+
### Installation
107+
108+
Add `concord` to your dependencies in `mix.exs`:
109+
110+
```elixir
111+
def deps do
112+
[
113+
{:concord, "~> ${{ github.event.inputs.version }}"}
114+
]
115+
end
116+
```
117+
118+
### Documentation
119+
120+
Documentation is available at: https://hexdocs.pm/concord/${{ github.event.inputs.version }}
121+
draft: false
122+
prerelease: false

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ concord-*.tar
2121

2222
# Temporary files, for example, from tests.
2323
/tmp/
24+
plts/
25+
26+
# devenv
27+
.devenv/
28+
.devenv.*

0 commit comments

Comments
 (0)