diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml index 355f49278..90219958f 100644 --- a/.github/workflows/build-and-check.yml +++ b/.github/workflows/build-and-check.yml @@ -1112,6 +1112,30 @@ jobs: mix local.hex --force mix local.rebar --force + # Before any publish. Each package's mix.exs takes its version from an + # env var (APP_VERSION for the SDK pair, GAMEND_CONTENT_APP_VERSION for + # core and web), so this repo's own image and docs carry the CI version. + # Shipped that way, a host compiled each package as whatever the var held + # on its machine: a Dockerfile exporting GAMEND_CONTENT_APP_VERSION=1.0.0 + # built gamend_core and gamend_web as 1.0.0, and the SDK pair, whose + # @version was never stamped, built as 1.0.26 wherever APP_VERSION was + # unset. Both failed a host's `>= 1.0.1266` floor with "the dependency + # does not match the requirement". The published mix.exs states the + # release's version and reads nothing. + - name: Pin the published package versions + run: | + for f in sdk/mix.exs sdk_tools/mix.exs apps/gamend_core/mix.exs apps/gamend_web/mix.exs; do + sed -i \ + -e "s|@version \"[^\"]*\"|@version \"${APP_VERSION}\"|" \ + -e "s#version: System.get_env(\"[A-Z_]*\") || @version,#version: @version,#" \ + "$f" + if ! grep -q "@version \"${APP_VERSION}\"" "$f" || ! grep -q "version: @version," "$f" || + grep -q "version: System.get_env" "$f"; then + echo "::error::$f: version pin failed - the package would read its version from the environment" + exit 1 + fi + done + - name: Publish gamend_sdk working-directory: sdk run: | @@ -1137,7 +1161,7 @@ jobs: mix hex.publish --yes fi - - name: Rewrite the gamend_core path dep and stamp versions + - name: Rewrite the gamend_core path dep run: | # gamend_web depends on gamend_core by path; Hex only accepts Hex # deps, so the published package points at the version being cut. @@ -1148,9 +1172,6 @@ jobs: apps/gamend_web/mix.exs grep -q '{:gamend_core, "~> 1.0"}' apps/gamend_web/mix.exs || { echo "::error::gamend_core path dep rewrite failed - gamend_web would publish broken"; exit 1; } - sed -i "s|@version \"[^\"]*\"|@version \"${APP_VERSION}\"|g" \ - apps/gamend_core/mix.exs \ - apps/gamend_web/mix.exs # Before gamend_web, which resolves gamend_core from the release this # step cuts. diff --git a/CHANGELOG.md b/CHANGELOG.md index d18e0af96..4a6db3178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # September 2026 +- [fixed] **The Hex packages compile as the version they were published as.** Each package's `mix.exs` took its version from the environment of whoever compiled it: `GAMEND_CONTENT_APP_VERSION` for gamend_core and gamend_web, `APP_VERSION` for gamend_sdk and gamend_plugin_tools. A host whose Dockerfile exports `GAMEND_CONTENT_APP_VERSION=1.0.0` (gamend_starter's did) built the engine as 1.0.0, and the SDK pair, whose `@version` publishing never stamped, built as 1.0.26 wherever `APP_VERSION` was unset. Either one failed a host's `>= 1.0.1266` requirement with "the dependency does not match the requirement". The publish job now writes the release's version into all four `mix.exs` files and removes the env lookup before anything is published; this repository's own image and docs still take the CI version from the environment. + - [fixed] **`GamendWeb.BrotliCompressor` no longer fails the digest when `brotli` is not installed.** Its docs promised that a missing binary keeps the gzip, but `System.cmd/3` raises `:enoent` for a command it cannot find, so a host that lists it in `:phoenix, :static_compressors` had `mix phx.digest`, and with it `mix assets.deploy`, crash on any machine without `brotli` on `PATH`. It now looks the binary up first and returns `:error` when it is missing, so the digest writes only the `.gz` files. - [fixed] **Slow-request log lines carried players' names and emails.** Sign in with Apple posts its callback with a `user` field holding the player's email and full name (on their first sign-in only), and that callback is routinely slow, so each new Apple player's details were written to the warning log, the admin Logs buffer, the log file and anything shipping logs off the host. `GamendWeb.Plugs.RequestTimer` now redacts `user`, any key containing `email` or `phone`, and `first_name`, `last_name`, `full_name` (and their unseparated spellings), as it already did credentials. Keys that merely contain a word, such as `user_count` or `name`, stay readable.