Add a blend dependency-version test matrix and CI dependency audits - #48
Merged
Conversation
blend (~> 0.5) generates per-blend lockfiles under blend/ so the suite can run against the dependency versions mix.exs claims to support, not just the frozen main lock: BLEND=<name> mix test.unit (or any mix task). Blends (see blend.exs): oldest (every direct dep at its declared floor, including waffle 1.1.0 which predates the bucket/1 callback), goth_1_2 (last pre-1.3 goth; the only config that compiles GothTokenFetcher), waffle_1_1_10, gcs_0_46, and mime_2 (resolvable because google_gax 0.4.0 has no mime dep). Supporting changes: - config/ split into the conventional per-env files; dev.exs and test.exs give credential-less runs a placeholder goth identity, because goth < 1.3 parses :json eagerly at app boot (before test_helper can run) and crashes on an unset GCP_CREDENTIALS. - test_helper excludes :integration and the new :goth_config_swap tag on old-goth runs (goth < 1.3 freezes boot config, so the signing tests' identity swap is impossible; integration needs the >= 1.3 API). Both exclusion blocks are commented for deletion at the goth version bump. - The test-support GothTokenFetcher is gated on goth >= 1.3, since Goth.fetch!/1 doesn't exist below it. - tesla becomes a direct dependency pinned to 1.18.2: newer tesla is incompatible with google_gax's compiled-in middleware stack. The pin raises the Elixir floor to ~> 1.15 and moves the hackney, finch, mint and hpax subtrees forward in the lock. - mix_audit is added and a mix audit alias runs the hex.audit and deps.audit dependency checks, honoring the ignore list in mix.exs. All five blends plus the default lock pass mix test.unit with and without credentials; the full integration suite passes on the default lock and the three network-capable blends.
The unit job gains an Elixir/OTP matrix from 1.15 (the floor in mix.exs) through 1.20, each paired with the newest OTP that version supports, plus one entry per blend on the newest pair — language compat is the version entries' job, dependency compat is the blends'. Blend runs need no blend package in CI: the committed premix.exs plus a BLEND env var is enough. They cache blend/<name>/deps keyed on the blend's own lockfile, and the cache keys drop the '**/mix.lock' glob so blend lock changes stop busting main-lock caches. New secret-free audit job runs mix audit (the hex.audit and deps.audit checks) and a blend drift check: mix blend.get must be a no-op against the committed lockfiles, so dependency changes that invalidate a blend fail loudly instead of silently testing a stale resolution. The integration job and the formatting check move to the newest pair.
petermueller
force-pushed
the
pkm/blend-dep-matrix
branch
from
July 26, 2026 03:25
dca6e83 to
71d62f2
Compare
…t blend waffle <= 1.1.9's generated delete/1 trips Elixir 1.20's type-checker warnings, which fail the unit job's --warnings-as-errors compile (the blend jobs that resolved waffle 1.1.10 already passed). Bump the main lock to waffle 1.1.10, and move the oldest blend — which pins waffle 1.1.0 deliberately — to the 1.15/OTP 26 floor pair, where no type warnings exist and which is the pairing floor-dep consumers actually run.
The tesla 1.18.2 exact pin forced by google_gax is transitive poison — it blocks consumers' own tesla usage from taking 1.18.3+ security fixes, and the archived upstream makes it permanent. Split the rewrite: phase 1 (Req transport, feature parity, library-owned types) gates 0.3; phase 2 (resumable, signBlob, v4, dual-target suite) targets 0.4. Transport default is Req, aligned with waffle core's direction (the Waffle.HTTPClient behaviour on master and the Req adapter in waffle PR #156).
A library's config files are never evaluated by consumers (see the Config module docs), so shipping config/config.exs was dead weight — and since the per-env split it references files that weren't in the tarball anyway. Verified with mix hex.build.
Common Changelog says to exclude maintenance changes that aren't interesting to consumers of the distributed package: the blend matrix, mix audit, the Mix.Config->Config switch, and the test-suite overhaul all fall under that. Dependency changes consumers can observe (tesla pin, mime, google_api_storage, jose, the Elixir floor) stay.
Identical findings on this lockfile (the same 5 tesla + 4 hackney advisories from both tools), and hex.audit additionally checks retirements and honors ignore_advisories natively. The audit alias becomes just hex.audit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds blend (
~> 0.5) so the suite can run against the dependency versions mix.exs claims to support, not just the frozen main lock:BLEND=<name> mix test.unit(or any mix task).oldestbucket/0fallback (waffle < 1.1.7 has nobucket/1)goth_1_2GothTokenFetcherwaffle_1_1_10gcs_0_46mime_2or ~> 2.0half of the mime requirementOld-goth blends are unit-only: test_helper excludes
:integration(the harness needs the Goth >= 1.3 API) and the two:goth_config_swapsigning tests (goth < 1.3 freezes boot config). Those exclusion blocks, theconfig/dev.exs+config/test.exsplaceholder-identity blocks, and the test-support fetcher gate all carry delete-me comments keyed to the future goth bump — removing a blend is deleting its entry,mix blend.get, done.Config is split into the conventional per-env files (
import_config "#{config_env()}.exs") so no test/dev shim can reach a release build.Dependencies
teslabecomes a direct dependency pinned to1.18.2(previously transitive viagoogle_gax): newer tesla is incompatible with google_gax's compiled-in middleware stack. Pinned pending the client rewrite (Client rewrite: replace google_api_storage / google_gax / legacy Goth with a minimal hand-rolled client #39). The pin raises the Elixir floor to~> 1.15and moves the hackney/finch/mint/hpax subtrees forward in the lock.mix_auditis added, and amix auditalias runs thehex.auditanddeps.auditdependency checks.CI
premix.exsand aBLENDenv var is enough — and cacheblend/<name>/depskeyed on the blend's own lockfile.auditjob:mix auditplus a blend drift check (mix blend.getmust be a no-op against the committed lockfiles).Testing
mix test.unitgreenmix audit,mix format --check-formatted, and the drift check green on Elixir 1.20.2 / OTP 29