CI: Credo, as a warning

3234b45 · gmorell · 2026-11-04 20:20

6 files +91 -1
Message
{commit_body(@commit)}

Files changed

added .credo.exs
+27 −0
@@ -0,0 +1,27 @@
1 +# Credo's default checks, with two changes: functions may nest one level
2 +# deeper than the default, and @moduledoc isn't required.
3 +# CI runs `mix credo` as a warning (.forgejo/workflows/credo.yml).
4 +%{
5 + configs: [
6 + %{
7 + name: "default",
8 + files: %{
9 + included: [
10 + "lib/",
11 + "src/",
12 + "test/",
13 + "web/",
14 + "apps/*/lib/",
15 + "apps/*/src/",
16 + "apps/*/test/",
17 + "apps/*/web/"
18 + ],
19 + excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
20 + },
21 + checks: %{
22 + extra: [{Credo.Check.Refactor.Nesting, [max_nesting: 3]}],
23 + disabled: [{Credo.Check.Readability.ModuleDoc, []}]
24 + }
25 + }
26 + ]
27 +}
added .forgejo/workflows/credo.yml
+60 −0
@@ -0,0 +1,60 @@
1 +name: credo
2 +# Credo's static analysis (.credo.exs), as a warning: the job runs under
3 +# `continue-on-error`, so what Credo finds marks the run ⚠ rather than
4 +# failing it.
5 +on:
6 + push:
7 + branches: [master]
8 + pull_request:
9 + workflow_dispatch:
10 +
11 +permissions:
12 + contents: read
13 +
14 +# A newer push supersedes this run: on a branch or PR the run in
15 +# progress is cancelled; on master it finishes, and only a run still
16 +# waiting is replaced.
17 +concurrency:
18 + group: ${{ github.workflow }}-${{ github.ref }}
19 + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
20 +
21 +jobs:
22 + credo:
23 + runs-on: self-hosted
24 + continue-on-error: true
25 + steps:
26 + - uses: actions/checkout@v4
27 +
28 + # `mix credo` compiles every dependency (not the app), so what the
29 + # Dockerfile's builder has for their NIFs.
30 + - name: Build dependencies
31 + run: |
32 + sudo apt-get update -q
33 + sudo apt-get install -y -q --no-install-recommends build-essential git pkg-config libssl-dev
34 +
35 + # OTP and Elixir from builds.hex.pm, the builds setup-beam would
36 + # fetch — taken directly, since setup-beam chooses one by ImageOS,
37 + # which this runner sets to "selfhosted" over anything a workflow
38 + # says.
39 + - name: OTP and Elixir
40 + env:
41 + OTP_VERSION: "28.5.0.8"
42 + ELIXIR_VERSION: "1.20.4"
43 + run: |
44 + ubuntu=$(. /etc/os-release && echo "$VERSION_ID")
45 + curl -sSfL "https://builds.hex.pm/builds/otp/ubuntu-${ubuntu}/OTP-${OTP_VERSION}.tar.gz" | tar xz -C /tmp
46 + # Installed where it's unpacked: Install's root is its own directory.
47 + (cd "/tmp/OTP-${OTP_VERSION}" && ./Install -minimal "/tmp/OTP-${OTP_VERSION}" > /dev/null)
48 + curl -sSfL -o /tmp/elixir.zip "https://builds.hex.pm/builds/elixir/v${ELIXIR_VERSION}-otp-${OTP_VERSION%%.*}.zip"
49 + unzip -q -d /tmp/elixir /tmp/elixir.zip
50 + echo "/tmp/OTP-${OTP_VERSION}/bin" >> "$GITHUB_PATH"
51 + echo /tmp/elixir/bin >> "$GITHUB_PATH"
52 +
53 + - name: Dependencies
54 + run: |
55 + mix local.hex --force
56 + mix local.rebar --force
57 + mix deps.get
58 +
59 + - name: Credo
60 + run: mix credo
modified mix.exs
+1 −0
@@ -50,6 +50,7 @@ defmodule ApollosCrib.MixProject do
50 50 # Run "mix help deps" for examples and options.
51 51 defp deps do
52 52 [
53 + {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
53 54 {:sentry, "~> 8.0"},
54 55 {:jason, "~> 1.1"},
55 56 # sentry 8 asks for ~> 1.8; see RoomSanctum.SentryClient.
modified mix.lock
+3 −1
@@ -3,6 +3,7 @@
3 3 "amqp_client": {:hex, :amqp_client, "4.2.1", "cff0cc13186e57457dc5745f1b3a4127c6857717cb8f5920dc457c84d0ad00a2", [:make, :rebar3], [{:credentials_obfuscation, "3.5.0", [hex: :credentials_obfuscation, repo: "hexpm", optional: false]}, {:rabbit_common, "4.2.1", [hex: :rabbit_common, repo: "hexpm", optional: false]}], "hexpm", "8ae00b055a58500e0557f73d9c0ffe257487131e603f7f84fe72cbfaaf03838a"},
4 4 "attrs": {:hex, :attrs, "0.6.0", "25d738b47829f964a786ef73897d2550b66f3e7d1d7c49a83bc8fd81c71bed93", [:mix], [], "hexpm", "9c30ac15255c2ba8399263db55ba32c2f4e5ec267b654ce23df99168b405c82e"},
5 5 "bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"},
6 + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
6 7 "castore": {:hex, :castore, "1.0.22", "a01978e6a5d42fa3a34143630588f92036e7d90e2309ecdd466722d1279a2213", [:mix], [], "hexpm", "c2a4d42723b4affbc1c3e15d8f6df3f7d8f1f627c84de643383634cce58493d5"},
7 8 "certifi": {:hex, :certifi, "2.18.0", "bd5f34eb8fe7c3eee3c705c1f9472174e8d4c353fc9c09a4cb937b891e80e329", [:rebar3], [], "hexpm", "a8b61115e393a2298b20451a36beffdabe08e61bc16cc1926d7991f6721103bf"},
8 9 "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
@@ -11,6 +12,7 @@
11 12 "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
12 13 "cowlib": {:hex, :cowlib, "2.21.0", "3ea757c79784bdbdebac7857ce3adf2290af6b8680d4248c75e40ced2e98c89e", [:make, :rebar3], [], "hexpm", "0960248773762a5319b3c17285028bc76f54f58ef0f9451367401bdf67b46274"},
13 14 "credentials_obfuscation": {:hex, :credentials_obfuscation, "3.5.0", "61e282adfb4439486b3994faaec69543c7ee6cc7e70c6340e8853fd9deaf8219", [:rebar3], [], "hexpm", "843adbe3246861ce0f1a0fa3222f384834eb31defd8d6b9cba7afd2977c957bc"},
15 + "credo": {:hex, :credo, "1.7.19", "cc52129665fc7c15143d47838fda0f9cd6dac9ceced7bf4da6f85fcbfe64b12a", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2d8bc95d5a7bb99dd2613621d4f08c6a3575c3fd4b62e6a2b48a100352a557b8"},
14 16 "csv": {:hex, :csv, "3.2.2", "452f96414b39a176b7c390af6d8b78f15130dc6167fe3b836729131f515d843e", [:mix], [], "hexpm", "cbf256ff74a3fa01d9ec420d07b19c90d410ed9fe5b6d6e1bc7662edf35bc574"},
15 17 "db_connection": {:hex, :db_connection, "2.10.2", "ae391e803a5adff104da913c2fc1c0c14a37f8b10001dcef568796e1fb7bf95c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "510b14482330f1af6490a2fa0efd8d4f1435d1529b165647df22ac0f2df0fa93"},
16 18 "decimal": {:hex, :decimal, "3.2.0", "f1235f05d841a211fda78a08fdb9777f2ff51a71f18455233fae186ff76187c6", [:mix], [], "hexpm", "190bca80580ce61aa69bb0eacadd7677710205c770225c2c2c07e32a5c31b234"},
@@ -88,7 +90,7 @@
88 90 "shards": {:hex, :shards, "1.1.1", "8b42323457d185b26b15d05187784ce6c5d1e181b35c46fca36c45f661defe02", [:make, :rebar3], [], "hexpm", "169a045dae6668cda15fbf86d31bf433d0dbbaec42c8c23ca4f8f2d405ea8eda"},
89 91 "solarex": {:hex, :solarex, "0.1.2", "549915e2440dbe8bcbb92e5b3592121281db2e30249f25813760c5d0f28f011f", [:mix], [{:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "d10d8eb855b8f5d1e968f6fa7070e6b1a3970d54ee30ab6fcc8d2301d163bdb9"},
90 92 "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"},
91 − "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.8", "5a1f8141a804262914345209f6f3d861e6b0b305f5c38257d99c77deec711c83", [], [], "hexpm", "004014f4927a8e463fece26b2b942df6578385b3e2f77c28b8dcf0bd7e9f36c7"},
93 + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.8", "5a1f8141a804262914345209f6f3d861e6b0b305f5c38257d99c77deec711c83", [:make, :mix, :rebar3], [], "hexpm", "004014f4927a8e463fece26b2b942df6578385b3e2f77c28b8dcf0bd7e9f36c7"},
92 94 "swoosh": {:hex, :swoosh, "1.27.0", "2df57c342f3854f2d429e6afebf19a03a179976a64006a93750ed81639453f75", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, ">= 1.9.0 and < 5.0.0", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, ">= 6.0.0 and < 8.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5da7d3b11de5d61327275ed599cb311942ea6e23cdbb411981f46ee150cddf76"},
93 95 "tailwind": {:hex, :tailwind, "0.3.1", "a89d2835c580748c7a975ad7dd3f2ea5e63216dc16d44f9df492fbd12c094bed", [:mix], [], "hexpm", "98a45febdf4a87bc26682e1171acdedd6317d0919953c353fcd1b4f9f4b676a2"},
94 96 "telemetry": {:hex, :telemetry, "1.4.2", "a0cb522801dffb1c49fe6e30561badffc7b6d0e180db1300df759faa22062855", [:rebar3], [], "hexpm", "928f6495066506077862c0d1646609eed891a4326bee3126ba54b60af61febb1"},

Parents: de11d74