Skip to content

chore(github_notifier) bump Alpine to 3.24.1, Elixir to 1.20.2, Erlang 29.0.3 - #1119

Open
adbatista wants to merge 38 commits into
mainfrom
adb/alpine-eol-vulnerability
Open

chore(github_notifier) bump Alpine to 3.24.1, Elixir to 1.20.2, Erlang 29.0.3#1119
adbatista wants to merge 38 commits into
mainfrom
adb/alpine-eol-vulnerability

Conversation

@adbatista

@adbatista adbatista commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

📝 Description

Fixes the OS-EOL-001 security finding in github_notifier (Alpine 3.20 reached end of life on 2026-04-01) by upgrading the base image to the current stable release and bringing the whole toolchain along:

  • Alpine 3.20.9 → 3.24.1
  • Elixir 1.13.4 → 1.20.2
  • Erlang/OTP 24.3.4.17 → 29.0.3.

The jump required modernizing the dependencies that pinned us to the old toolchain, most notably:

  • grpc (git fork → 0.9.0) with protobuf 0.5.4 → 0.13.0 (full .pb.ex regeneration)
  • AMQP stack 3.x → 4.x
  • tackle → v0.3.0
  • plus small OTP/Elixir compatibility fixes in feature_provider.

The upgrade is split into one-version-per-commit steps, each verified with a green build, full test suite, lint, and prod release build, so any intermediate toolchain version is a clean revert point.

Component Before After
Alpine 3.20.9 (EOL) 3.24.1
Elixir 1.13.4 (EOL) 1.20.2
Erlang/OTP 24.3.4.17 (EOL) 29.0.3
grpc git fork (eff8a88) 0.9.0 (hex)
protobuf 0.5.4 0.13.0 (regenerated .pb.ex)
amqp / amqp_client / rabbit_common 3.3.0 / 3.12.14 / 3.12.14 4.1.1 / 4.2.1 / 4.2.1
tackle old ref (c15832a) v0.3.0
cowboy / cowlib / ranch / gun 2.8.0 / 2.9.1 / 1.7.1 / grpc_gun 2.0.0 2.17.0 / 2.18.0 / 2.2.0 / gun 2.4.1
credo 1.6.4 1.7.19
mix_test_watch 1.1.0 1.4.0
watchman b7a205b 1ff788c

✅ Checklist

  • I have tested this change
  • This change requires documentation update

adbatista added 21 commits July 22, 2026 11:07
- bump watchman git ref to 1ff788c (old ref fails to compile on Elixir >= 1.15)
- prune unused mix.lock entries (lager, goldrush, jsx, meck, mock, ranch_proxy_protocol, fun_registry)
- bump credo to 1.7.19 (1.6.4 crashes on Elixir 1.18); rename is_passed?/is_failed? to passed?/failed? per stricter PredicateFunctionNames check
- replace deprecated Logger.warn with Logger.warning
Alpine 3.20 reached end of life on 2026-04-01; 3.22 is supported
until 2027-05-01 and is the newest cycle published for the
elixir 1.13.4 / OTP 24.3.4.17 builder image.
Old ref's consumer macros emit type-system warnings on Elixir >= 1.18,
failing --warnings-as-errors builds. v0.3.0 is the ref used by
hooks_processor and repository_hub.
- grpc: git eff8a88 -> hex 0.9.0 (drops grpc_gun fork and cowlib 2.9 pin;
  brings gun 2.4, cowboy 2.17, ranch 2.2, mint)
- grpc_mock: switch to grpc08 branch (grpc 0.9 compatible)
- protobuf: 0.5.4 -> 0.13.0; regenerate lib/internal_api with
  protoc-gen-elixir 0.13.0 and add google/rpc + plumber_w_f +
  google/protobuf/any to the generation list (compile-time enum
  resolution requires the full import closure)
- serve the API through a GRPC.Endpoint module (new supervisor API)
- replace deprecated Message.new/enum key()/value() with struct
  syntax and decoded atom enums; strip protobuf metadata from the
  Poison-round-tripped project status map

Old grpc macros fail --warnings-as-errors on Elixir >= 1.17
(map.field deprecation), blocking further toolchain rungs.
…tibility

rabbit_common 3.12 fails to compile on OTP 27 ('maybe' became a
reserved word). Overrides follow the ee/rbac pattern; ranch is pinned
to 2.1.0 which both rabbit_common 3.13 and cowboy 2.17 accept.
- handle nil __CALLER__.function in log_fun macro (Elixir 1.18 type
  checker flags elem/2 on nil | tuple)
- bump ssl_verify_fun to 1.1.7 (1.1.6 fails to compile on OTP 26+)
  with certifi/hackney lock refresh (test-only deps)
mix_test_watch 1.1.0 fails to compile on Elixir 1.19 (Regex struct
default no longer allowed); bumped to 1.4.0 (dev/test-only dep).
rabbit_common 3.13 fails to compile on OTP 28 (public_key OID macros
such as 'street-address' were removed). Moved the AMQP stack to the
4.x line (amqp 4.1.1, amqp_client/rabbit_common 4.2.1), overriding
tackle's amqp ~> 3.3 constraint; ranch settles back to 2.2.0.
Elixir 1.20 fallout, all under --warnings-as-errors:
- tackle consumers: pass dead_letter_queue via Application.get_env so
  the type checker no longer flags the macro's always-true conditional
- switch Sentry logger backend registration to the logger_backends
  package (Logger.add_backend/configure_backend are deprecated)
- drop unused require Logger/GrpcMock in api.ex and test files
Credo 1.7's MissedMetadataKeyInLoggerConfig fails CI: consumers set
request_id via Logger.metadata/1 but only dev config declared it.
Dependency scan (Check dependencies job) flags:
- hackney 1.20.1: GHSA-mp55-p8c9-rfw2, GHSA-pj7v-xfvx-wmjq,
  GHSA-vq52-99r9-h5pw - first patched in 4.0.1
- protobuf 0.13.0: GHSA-rv48-qqj5-crxg (unbounded recursion) -
  first patched in 0.16.1

Changes:
- hackney -> 4.6 via httpoison 3.0 (override; tentacat 2.5 still
  pins httpoison ~> 2.0) and sentry -> 13.3 (sentry 8 capped
  hackney at 1.x); Sentry.LoggerBackend replaced with the
  Sentry.LoggerHandler :logger handler, HackneyClient configured,
  removed config keys (included_environments) migrated, source
  code packaged in the release build step
- protobuf -> 0.17 with regenerated stubs (plugin 0.17 emits
  per-package directories); bundled well-known types
  (Google.Protobuf.*) are no longer generated locally to avoid
  module redefinition; Poison round-trip now also strips the
  __protobuf__ marker
…_audit

hackney 4.x requires an httpoison 3 / sentry 13 migration and
protobuf 0.16+ requires regenerating all internal_api stubs; both
upgrades are deferred to a dedicated PR. Advisories are documented
and justified in .mix-audit.txt (same pattern as front/).
@adbatista adbatista changed the title chore(github_notifier) chore(github_notifier) bump Alpine to 3.24.1, Elixir to 1.20.2, Erlang 29.0.3 Jul 23, 2026
hackney/certifi/mimerl/parse_trans/unicode_util_compat bumps were
collateral of the ssl_verify_fun update; only ssl_verify_fun 1.1.7 is
required (1.1.6 fails to compile on OTP 26+). Test-only deps revert
to their previous versions.
adbatista added 11 commits July 23, 2026 13:18
make test wrapped everything in docker compose whenever docker was
present, so every matrix cell ran the Dockerfile's elixir 1.14 image
and sem-version's Erlang/Elixir was never exercised. Gate
maybe_call_in_docker on CI so jobs run mix directly on the toolchain
under test; docker compose remains the local default.

Also trim the matrix to installable, officially supported pairs
(elixir 1.10/1.11 have no ubuntu2404 prebuilts and each elixir only
supports a window of OTP majors) and bootstrap rebar in the prologue
for rebar3-built deps.
'test: MIX_ENV=test' sets a make variable without exporting it to the
environment, so the direct (non-docker) path ran mix in the dev env
and 'mix test' aborted. The docker path masked this because
docker-compose.yml sets MIX_ENV itself.
… 1.19/1.20)

Removal in 6868130 failed 6 cells: rebar3 is installed per elixir-otp
version dir, and fresh 1.19/1.20 installs have none, so rebar-built deps
(sleeplocks) fail to compile. Added a comment to prevent re-removal.
Bare 'cache restore'/'cache store' shared one bucket across all 27
matrix cells, so a _build compiled under one Elixir/OTP could be
restored into a job on another, making rebar fail to link sleeplocks
(OTP BEAM mismatch). Key deps and _build caches on
ERLANG_VERSION-ELIXIR_VERSION-checksum(mix.lock) so each cell is
isolated.
Earlier necessity test was confounded by cache poisoning; re-test now
that caches are keyed per toolchain. Revert if any cell fails on a
missing rebar3.
Temporary: mix.lock unchanged means the keyed caches from the prior
run would be hit and skip compilation, masking whether rebar is
needed. v2 forces every cell to compile a rebar dep fresh with no
mix local.rebar present -- a clean single-variable test.
The /docs/docs and /docs/versioned_docs clauses lacked
pipeline_file: 'ignore', so any edit to .semaphore/semaphore.yml
forced the whole MCP Server block to run (Semaphore treats every
non-opted-out change_in as true when the pipeline file changes).
Match the mcp_server path clause so the block runs only on real
mcp_server/docs content changes.
…2 nonce

Cold-cache run proved the line load-bearing: without it, a fresh
compile aborts non-interactively with 'Could not find rebar3, needed
to build dependency :parse_trans'. sem-version does not seed rebar3.
The earlier warm-cache pass only skipped compilation. Reverts the
temporary v2 cache-key nonce back to the stable key.
Drop the Erlang 23 row; scope Erlang 24 to Elixir 1.11-1.14 (1.11
has a prebuilt only on OTP 24/25), and Erlang 25/26 to 1.15-1.18.
@adbatista
adbatista marked this pull request as ready for review July 24, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants