Release/3.19.0 - #6
Merged
Merged
Conversation
The vendored 1.1.0 tree under //third_party/rules_elixir is now released as
1.2.0 from bazelverse/rules_elixir, carrying the same eight local fixes plus the
mix_archive_build rule and hex extension this repository depends on. Pinned by
commit rather than tag so the pin is immutable; it is not on the Bazel Central
Registry yet, so the override goes when it is published.
Deletes 75 vendored files and the .bazelignore entry that kept them out of
package discovery. Verified in the order that never leaves a broken tree: built
//elixir/... against the remote first, deleted the tree second. Every file in
the vendored tree was byte-identical to the release beforehand, so the only
content this drops is VENDORING.md, whose rationale now lives in that
repository's CHANGELOG.
Both rulesets are now consumed the same way, which is the point: rules_erlang
and rules_elixir are maintained upstream again rather than as copies nobody
outside this repository can see. Two fixes in 1.2.0 came from that move, since
neither is reachable from here:
- ex_unit_test resolves @platforms//os:windows through Label() rather than a
bare string. As a string the key resolved against the repo mapping of the
package instantiating the macro, so it only worked for consumers that
happened to declare bazel_dep(name = "platforms") themselves. This
repository does, which is exactly why the vendored copy never showed it.
- ex_unit_test detects results by exit code rather than by matching the ExUnit
summary. Elixir 1.20 replaced "N tests, M failures" with "Result: N passed",
which failed every passing suite. The one remaining summary check, that a
target which ran no tests and excluded none is a defect, is what the five
tag-filtered shards here caught: excluding everything you were asked to
exclude is not a defect.
Verified: bazel test -c opt --config=ci //... --test_tag_filters=-integration_test,-acceptance_test
passes 142 tests, with the five Elixir shards force-executed rather than cached.
Nine select() keys named "@platforms//os:windows" as a bare string. A select key
written as a string resolves against the repo mapping of the package that
instantiates it, and all nine live in macros a consumer calls from its own
BUILD.bazel. So the key resolved in the consumer's module, and any consumer that
had not declared bazel_dep(name = "platforms") of its own failed analysis:
ERROR: no such package '@@[unknown repo 'platforms' requested from @@]//os':
No repository visible as '@platforms' from main repository
ERROR: errors encountered resolving select() keys for //:xref
Calling xref, dialyze, eunit, ct_suite or shell was enough to trigger it. The
keys are Labels now, which resolve against this module's repo mapping, and
platforms is declared here where it belongs.
3.18.0 introduced this by migrating off @bazel_tools//src/conditions:host_windows.
The question could not arise for the old key, since bazel_tools is an implicit
dependency of every module and is visible everywhere. It survived reldependency of eth consumers on hand happened to depend on platforms already, this
repository's own test module among them, so nothing in CI could see it.
RRRRRRRRRRRRRRRRRRRRRRR consumer that declares nothing but rules_erlang, whiRRRRRRRRRRRRRRRRRRR and builds on this commit.
The condition lives in one place now. Nine copies of a three-line select is the
shape of a fix that lands in shape of hem and not the rest, which is what
happened to the allow_empty glob fix in 3.18.0.
One fix, for a bug 3.18.0 introduced. Drop-in for both 3.18.0 and 3.16.0. The README also drops archive_override in favour of git_override, matching rules_elixir, and states that a consumer needs no platforms dependency of its own. Signed-off-by: Marvin Hansen <marvin.hansen@gmail.com>
Adds prebuilt_erlang_from_http_archive and prebuilt_erlang_from_hex_builds, a third way to provide OTP alongside the existing external and internal paths. Neither existing path covers a downloadable prebuilt. external_erlang_from_path takes an absolute erlang_home that must already exist on whatever machine runs the action -- a host dependency, and unsatisfiable on a remote executor without baking OTP into the executor image. internal_erlang_from_http_archive accepts any URL but always feeds it to erlang_build, which runs ./configure && make; pointing it at a binary release does not skip the build, it fails, because there is nothing to configure. So a consumer who wanted a prebuilt OTP had to compile one anyway. Measured on the same target and machine with both caches defeated via --action_env, OTP 28.1 on linux/amd64: the from-source path was still compiling after five minutes and was abandoned; the prebuilt path completed in ~12s wall, of which the staging action was 3-8s. The download is 71 MB for a 171 MB installed tree. On relocation. An OTP installation is not relocatable -- ROOTDIR is written into the generated start scripts at install time, which is why a binary release ships an Install script at all. `Install -cross <TARGET>` treats the current directory as the staging location while writing TARGET into the scripts, and that is exactly the split this rule needs: staging happens in a sandbox, but the install path is fixed and absolute. The rule fails with an explicit message when the archive has no executable Install at its root, because the likely mistake is passing an otp_src tarball, and the resulting error otherwise surfaces deep inside the action as a missing ./configure. On the output contract. erlang_prebuilt returns the same release_dir_tar and version_file that erlang_build does, and validates the same way -- unpack where the installation will actually live, run erl, and compare what it reports against the declared version rather than trusting the attribute. The toolchain cannot tell the two rules apart. On toolchain registration. A prebuilt installation registers under the existing :erlang_internal constraint rather than a new one. It is hermetic in the same sense an internally built one is: fetched and staged by the build, not discovered on the host. Reusing the constraint keeps the generated target names identical, so moving a repository between the source and prebuilt paths is a MODULE.bazel edit and nothing else -- existing toolchain_resolution_overrides and //<name>:toolchain_major references keep resolving. On multiple architectures. Both tag classes take exec_compatible_with, appended to the generated toolchain's own exec_compatible_with. A repository can register one prebuilt per execution architecture and let toolchain resolution choose between them, which is what makes a prebuilt OTP useful for something other than the machine that happens to be building. prebuilt_erlang_from_hex_builds is a thin convenience over builds.hex.pm, which publishes a release per (arch, os) and lists each archive's sha256 in its builds.txt. The checksum a consumer pins is therefore one upstream already publishes, rather than one produced by mirroring the archive somewhere to compute it. Note that hex.pm publishes arm64 only for ubuntu-22.04 and ubuntu-24.04; the other distributions are amd64-only, and the os value has to match the runtime's libc. Verified against a monorepo whose Elixir build was switched to the prebuilt path: the OTP stages and erl runs correctly from the relocated install reporting 28.1, and five Elixir test suites compile and pass through it. This repository's own three tests pass (forced, not cached). Not covered: there is no test here exercising erlang_prebuilt. The test workspace registers its OTP toolchains by name, so adding one means a second registered installation and the resolution ambiguity that comes with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marvin Hansen <marvin.hansen@gmail.com>
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.
merging all commits from the 3.19 branch