diff --git a/.credo.exs b/.credo.exs index cfc55eb..93bffde 100644 --- a/.credo.exs +++ b/.credo.exs @@ -1,3 +1,5 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + # This file contains the configuration for Credo and you are probably reading # this after creating it with `mix credo.gen.config`. # @@ -21,16 +23,7 @@ # You can give explicit globs or simply directories. # In the latter case `**/*.{ex,exs}` will be used. # - included: [ - "lib/", - "src/", - "test/", - "web/", - "apps/*/lib/", - "apps/*/src/", - "apps/*/test/", - "apps/*/web/" - ], + included: ["config/", "lib/", "priv/", "test/"], excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"] }, # @@ -46,7 +39,7 @@ # If you want to enforce a style guide and need a more traditional linting # experience, you can change `strict` to `true` below: # - strict: false, + strict: true, # # To modify the timeout for parsing files, change this value: # @@ -70,10 +63,12 @@ # {Credo.Check.Consistency.ExceptionNames, []}, {Credo.Check.Consistency.LineEndings, []}, + {Credo.Check.Consistency.MultiAliasImportRequireUse, []}, {Credo.Check.Consistency.ParameterPatternMatching, []}, {Credo.Check.Consistency.SpaceAroundOperators, []}, {Credo.Check.Consistency.SpaceInParentheses, []}, {Credo.Check.Consistency.TabsOrSpaces, []}, + {Credo.Check.Consistency.UnusedVariableNames, false}, # ## Design Checks @@ -81,7 +76,8 @@ # You can customize the priority of any check # Priority values are: `low, normal, high, higher` # - {Credo.Check.Design.AliasUsage, [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]}, + {Credo.Check.Design.AliasUsage, [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 2]}, + {Credo.Check.Design.DuplicatedCode, false}, # You can also customize the exit_status of each check. # If you don't want TODO comments to cause `mix credo` to fail, just # set this value to 0 (zero). @@ -92,39 +88,61 @@ # ## Readability Checks # + {Credo.Check.Readability.AliasAs, false}, {Credo.Check.Readability.AliasOrder, []}, + {Credo.Check.Readability.BlockPipe, []}, {Credo.Check.Readability.FunctionNames, []}, - {Credo.Check.Readability.LargeNumbers, []}, - {Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]}, + {Credo.Check.Readability.ImplTrue, []}, + {Credo.Check.Readability.LargeNumbers, [trailing_digits: 2]}, + {Credo.Check.Readability.MaxLineLength, false}, {Credo.Check.Readability.ModuleAttributeNames, []}, - {Credo.Check.Readability.ModuleDoc, []}, + {Credo.Check.Readability.ModuleDoc, false}, {Credo.Check.Readability.ModuleNames, []}, + {Credo.Check.Readability.MultiAlias, false}, + {Credo.Check.Readability.NestedFunctionCalls, []}, {Credo.Check.Readability.ParenthesesInCondition, []}, {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []}, {Credo.Check.Readability.PredicateFunctionNames, []}, {Credo.Check.Readability.PreferImplicitTry, []}, {Credo.Check.Readability.RedundantBlankLines, []}, {Credo.Check.Readability.Semicolons, []}, + {Credo.Check.Readability.SeparateAliasRequire, []}, + {Credo.Check.Readability.SinglePipe, []}, {Credo.Check.Readability.SpaceAfterCommas, []}, + {Credo.Check.Readability.Specs, false}, + {Credo.Check.Readability.StrictModuleLayout, + [ + order: + ~w(moduledoc behaviour use import require alias module_attribute defstruct callback macrocallback optional_callback)a, + ignore: [:type] + ]}, {Credo.Check.Readability.StringSigils, []}, {Credo.Check.Readability.TrailingBlankLine, []}, {Credo.Check.Readability.TrailingWhiteSpace, []}, {Credo.Check.Readability.UnnecessaryAliasExpansion, []}, {Credo.Check.Readability.VariableNames, []}, + {Credo.Check.Readability.WithCustomTaggedTuple, []}, # ## Refactoring Opportunities # + {Credo.Check.Refactor.ABCSize, false}, + {Credo.Check.Refactor.AppendSingleItem, []}, {Credo.Check.Refactor.CondStatements, []}, {Credo.Check.Refactor.CyclomaticComplexity, []}, + {Credo.Check.Refactor.DoubleBooleanNegation, []}, {Credo.Check.Refactor.FunctionArity, []}, {Credo.Check.Refactor.LongQuoteBlocks, []}, # {Credo.Check.Refactor.MapInto, []}, {Credo.Check.Refactor.MatchInCondition, []}, + {Credo.Check.Refactor.ModuleDependencies, false}, {Credo.Check.Refactor.NegatedConditionsInUnless, []}, {Credo.Check.Refactor.NegatedConditionsWithElse, []}, + {Credo.Check.Refactor.NegatedIsNil, []}, {Credo.Check.Refactor.Nesting, []}, + {Credo.Check.Refactor.PipeChainStart, []}, {Credo.Check.Refactor.UnlessWithElse, []}, + {Credo.Check.Refactor.VariableRebinding, false}, {Credo.Check.Refactor.WithClauses, []}, # @@ -135,11 +153,18 @@ {Credo.Check.Warning.ExpensiveEmptyEnumCheck, []}, {Credo.Check.Warning.IExPry, []}, {Credo.Check.Warning.IoInspect, []}, + {Credo.Check.Warning.LeakyEnvironment, []}, # {Credo.Check.Warning.LazyLogging, []}, - {Credo.Check.Warning.MixEnv, false}, + {Credo.Check.Warning.MapGetUnsafePass, []}, + # disabling this check by default, as if not included, it will be + # run on version 1.7.0 and above + {Credo.Check.Warning.MissedMetadataKeyInLoggerConfig, false}, + {Credo.Check.Warning.MixEnv, []}, {Credo.Check.Warning.OperationOnSameValues, []}, {Credo.Check.Warning.OperationWithConstantResult, []}, {Credo.Check.Warning.RaiseInsideRescue, []}, + {Credo.Check.Warning.UnsafeExec, []}, + {Credo.Check.Warning.UnsafeToAtom, []}, {Credo.Check.Warning.UnusedEnumOperation, []}, {Credo.Check.Warning.UnusedFileOperation, []}, {Credo.Check.Warning.UnusedKeywordOperation, []}, @@ -148,40 +173,6 @@ {Credo.Check.Warning.UnusedRegexOperation, []}, {Credo.Check.Warning.UnusedStringOperation, []}, {Credo.Check.Warning.UnusedTupleOperation, []}, - {Credo.Check.Warning.UnsafeExec, []}, - - # - # Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`) - - # - # Controversial and experimental checks (opt-in, just replace `false` with `[]`) - # - {Credo.Check.Consistency.MultiAliasImportRequireUse, false}, - {Credo.Check.Consistency.UnusedVariableNames, false}, - {Credo.Check.Design.DuplicatedCode, false}, - {Credo.Check.Readability.AliasAs, false}, - {Credo.Check.Readability.BlockPipe, false}, - {Credo.Check.Readability.ImplTrue, false}, - {Credo.Check.Readability.MultiAlias, false}, - {Credo.Check.Readability.SeparateAliasRequire, false}, - {Credo.Check.Readability.SinglePipe, false}, - {Credo.Check.Readability.Specs, false}, - {Credo.Check.Readability.StrictModuleLayout, false}, - {Credo.Check.Readability.WithCustomTaggedTuple, false}, - {Credo.Check.Refactor.ABCSize, false}, - {Credo.Check.Refactor.AppendSingleItem, false}, - {Credo.Check.Refactor.DoubleBooleanNegation, false}, - {Credo.Check.Refactor.ModuleDependencies, false}, - {Credo.Check.Refactor.NegatedIsNil, false}, - {Credo.Check.Refactor.PipeChainStart, false}, - {Credo.Check.Refactor.VariableRebinding, false}, - {Credo.Check.Warning.LeakyEnvironment, false}, - {Credo.Check.Warning.MapGetUnsafePass, false}, - {Credo.Check.Warning.UnsafeToAtom, false} - - # - # Custom checks can be created using `mix credo.gen.check`. - # ] } ] diff --git a/.formatter.exs b/.formatter.exs index eb0477f..e287cec 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,8 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + [ - inputs: ["*.{ex,exs}", "{lib,test}/**/*.{ex,exs}", "example/{lib,test}/**/*.{ex,exs}"], - line_length: 120 + import_deps: [], + inputs: ["*.{heex,ex,exs}", "{config,lib,priv,test}/**/*.{heex,ex,exs}"], + line_length: 120, + plugins: [] ] diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 0000000..cd8b23a --- /dev/null +++ b/.github/release-please-config.json @@ -0,0 +1,39 @@ +{ + "$comment": "This file is synced with beam-community/common-config. Any changes will be overwritten.", + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "changelog-sections": [ + { + "type": "feat", + "section": "Features", + "hidden": false + }, + { + "type": "fix", + "section": "Bug Fixes", + "hidden": false + }, + { + "type": "chore", + "section": "Miscellaneous", + "hidden": false + } + ], + "draft": false, + "draft-pull-request": false, + "packages": { + ".": { + "extra-files": [ + "README.md" + ], + "release-type": "elixir" + } + }, + "plugins": [ + { + "type": "sentence-case" + } + ], + "prerelease": false, + "pull-request-header": "An automated release has been created for you.", + "separate-pull-requests": true +} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..f3f57ac --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,121 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: CI + +on: + merge_group: + pull_request: + types: + - opened + - reopened + - synchronize + push: + branches: + - main + workflow_call: + secrets: + GH_PERSONAL_ACCESS_TOKEN: + required: true + workflow_dispatch: + +concurrency: + group: CI ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + Credo: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Credo + run: mix credo --strict + + Dependencies: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Unused + run: mix deps.unlock --check-unused + + Dialyzer: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Dialyzer + run: mix dialyzer --format github + + Format: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Format + run: mix format --check-formatted + + Test: + name: Test (Elixir ${{ matrix.versions.elixir }} OTP ${{ matrix.versions.otp }}) + + runs-on: ubuntu-latest + + env: + MIX_ENV: test + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + elixir-version: ${{ matrix.versions.elixir }} + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + otp-version: ${{ matrix.versions.otp }} + + - name: Compile + run: mix compile --warnings-as-errors + + - name: Test + run: mix test + + strategy: + fail-fast: false + matrix: + versions: + - elixir: 1.13 + otp: 25 + - elixir: 1.14 + otp: 25 + - elixir: 1.15 + otp: 26 + diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000..5e2628a --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,35 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: PR + +on: + merge_group: + pull_request: + types: + - edited + - opened + - reopened + - synchronize + +jobs: + Title: + if: ${{ github.event_name == 'pull_request' }} + name: Check Title + runs-on: ubuntu-latest + + steps: + - name: Check + uses: stordco/actions-pr-title@v1.0.0 + with: + regex: '^(feat!|fix!|fix|feat|chore)(\(\w+\))?:\s(\[#\d{1,5}\])?.*$' + hint: | + Your PR title does not match the Conventional Commits convention. Please rename your PR to match one of the following formats: + + fix: [#123] some title of the PR + fix(scope): [#123] some title of the PR + feat: [#1234] some title of the PR + chore: update some action + + Note: Adding ! (i.e. `feat!:`) represents a breaking change and will result in a SemVer major release. + + See https://www.conventionalcommits.org/en/v1.0.0/ for more information. diff --git a/.github/workflows/production.yaml b/.github/workflows/production.yaml new file mode 100644 index 0000000..6304a1e --- /dev/null +++ b/.github/workflows/production.yaml @@ -0,0 +1,35 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: Production + +on: + release: + types: + - released + - prereleased + workflow_dispatch: + +concurrency: + group: Production + +jobs: + Hex: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Compile + run: mix compile --docs + + - name: Publish + run: mix hex.publish --yes + env: + HEX_API_KEY: ${{ secrets.HEX_API_KEY }} + diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..40ef723 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,23 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: Release + +on: + push: + branches: + - main + +jobs: + Please: + runs-on: ubuntu-latest + + steps: + - id: release + name: Release + uses: google-github-actions/release-please-action@v3 + with: + command: manifest + config-file: .github/release-please-config.json + manifest-file: .github/release-please-manifest.json + release-type: elixir + token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}