From f6f3b4f03a42b2dceb12b3425b0ff2ed495e6f69 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 12:31:59 +0200 Subject: [PATCH 01/17] fix some test setup for github action --- .github/workflows/test.yaml | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c818c2f6..ce361fe0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -3,13 +3,11 @@ on: push: branches: - main - - 3.15.x - - 3.16.x - - bump-rbe + - develop pull_request: jobs: unit-test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -18,7 +16,7 @@ jobs: - "26.2" steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 with: @@ -30,7 +28,7 @@ jobs: --noenable_bzlmod \ --color=yes unit-test-bzlmod: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -39,7 +37,7 @@ jobs: - "26.2" steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 with: @@ -50,7 +48,7 @@ jobs: bazelisk test //... \ --color=yes test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -59,7 +57,7 @@ jobs: - "26.2" steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 with: @@ -84,7 +82,7 @@ jobs: name: bazel-testlogs-${{matrix.otp}} path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-bzlmod: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -93,7 +91,7 @@ jobs: - "26.2" steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 with: @@ -119,7 +117,7 @@ jobs: runs-on: macos-latest steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG run: | brew install erlang @@ -150,7 +148,7 @@ jobs: - "25.3" steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 with: @@ -187,10 +185,10 @@ jobs: name: bazel-testlogs-bzlmod-windows-${{matrix.otp}} path: test/logs.tar test-bzlmod-internal-erlang: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE BAZEL working-directory: test run: | @@ -226,10 +224,10 @@ jobs: name: bazel-testlogs-bzlmod-internal-erlang path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-bzlmod-coverage: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 # - name: INSTALL LCOV # run: | # sudo apt-get install -y lcov @@ -259,10 +257,10 @@ jobs: name: bazel-testlogs-bzlmod-coverage path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-host-erlang-change-detected: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - name: CHECKOUT - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 with: From bf963485580696007003c29deeecabf2c13404a8 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 14:08:04 +0200 Subject: [PATCH 02/17] update upload-artifact@v7 --- .github/workflows/test.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ce361fe0..3b7ab798 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -77,7 +77,7 @@ jobs: id: resolve-test-logs-path - name: CAPTURE TEST LOGS if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: bazel-testlogs-${{matrix.otp}} path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* @@ -109,7 +109,7 @@ jobs: id: resolve-test-logs-path - name: CAPTURE TEST LOGS if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: bazel-testlogs-bzlmod-${{matrix.otp}} path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* @@ -135,7 +135,7 @@ jobs: id: resolve-test-logs-path - name: CAPTURE TEST LOGS if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: bazel-testlogs-bzlmod-macos path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* @@ -180,7 +180,7 @@ jobs: tar -cf $LOGS_TAR * - name: CAPTURE TEST LOGS if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: bazel-testlogs-bzlmod-windows-${{matrix.otp}} path: test/logs.tar @@ -219,7 +219,7 @@ jobs: id: resolve-test-logs-path - name: CAPTURE TEST LOGS if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: bazel-testlogs-bzlmod-internal-erlang path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* @@ -252,7 +252,7 @@ jobs: id: resolve-test-logs-path - name: CAPTURE TEST LOGS if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: bazel-testlogs-bzlmod-coverage path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* From 8faae61a06455e5f49bd5734f07c1b55154f4618 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 14:57:33 +0200 Subject: [PATCH 03/17] Resurrect CI: pin Bazel 8.4.2, fix glob/sh_test defaults, fix CT/test regressions The repository's GitHub Actions workflow had been failing for some time due to a combination of Bazel version drift (last_rc -> 9.1.1rc1), breaking changes in Bazel's glob and sh_test defaults, and regressions in the rule implementations and test data. Infrastructure (Bazel 8.4.2 + stricter glob/sh_test defaults): - .bazelversion: last_rc -> 8.4.2 - erlang_app.bzl: allow_empty=True on 9 native.glob sites (include/, etc.) - ct.bzl: allow_empty=True on the 2 globs in ct_suite/ct_suite_variant - test/MODULE.bazel: platforms 0.0.7 -> 0.0.11; add rules_shell 0.6.1 - test/app_file/BUILD.bazel: switch app_file to public load; load sh_test from @rules_shell (no longer in @bazel_tools by default) CT/eunit regressions introduced in 228b062 "Fix testing support (ct, eunit)": - private/ct.bzl: flat_deps(deps + compiled_suites) -> flat_deps(deps); compiled_suites are .beam files, not ErlangAppInfo providers, so passing them through flat_deps causes an analysis-time error - private/ct.bzl: ct_run -dir ebin -> -dir test; the ct_suite macro still compiles SUITEs to dest="test", so -dir ebin found no suites Test data updates for product changes: - test/shard_suite/BUILD.bazel: erlang_bytecode2 -> erlang_bytecode v1 (v1 accepts string-list erlc_opts); replace eunit(compiled_suites=...) (no such attr) with test_beam=[...] on test_erlang_app + eunit_mods - test/rules_erlang_compiler/test/dot_app_file_SUITE.erl: add test_modules => [] to the Target map (228b062 made the key mandatory in dot_app_file:render/3 but did not update the test) Product bug fix: - tools/rebar_config_to_erlc_opts/src/rebar_config_to_erlc_opts.erl: honor no_debug_info in rebar.config erl_opts by dropping the default +debug_info from the output when no_debug_info is present; also lists:flatten the io_lib:format result so output entries are flat strings rather than nested iolists like [[43],"deterministic"] Local result with Bazel 8.4.2: 13/13 tests pass in test/. --- .bazelversion | 2 +- ct.bzl | 4 +- erlang_app.bzl | 13 ++-- private/ct.bzl | 4 +- test/MODULE.bazel | 6 +- test/app_file/BUILD.bazel | 3 +- .../test/dot_app_file_SUITE.erl | 3 +- test/shard_suite/BUILD.bazel | 60 ++++++++++--------- .../src/rebar_config_to_erlc_opts.erl | 11 +++- 9 files changed, 63 insertions(+), 43 deletions(-) diff --git a/.bazelversion b/.bazelversion index f4790dbf..e7fdef7e 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -last_rc +8.4.2 diff --git a/ct.bzl b/ct.bzl index 8079b619..b3a534f9 100644 --- a/ct.bzl +++ b/ct.bzl @@ -40,7 +40,7 @@ def ct_suite( erlang_bytecode( name = "{}_beam_files".format(suite_name), - hdrs = native.glob(["include/*.hrl", "src/*.hrl"] + additional_hdrs), + hdrs = native.glob(["include/*.hrl", "src/*.hrl"] + additional_hdrs, allow_empty = True), srcs = ["test/{}.erl".format(suite_name)] + additional_srcs, erlc_opts = erlc_opts, dest = "test", @@ -69,7 +69,7 @@ def ct_suite_variant( if suite_name == "": suite_name = name - data_dir_files = native.glob(["test/{}_data/**/*".format(suite_name)]) + data_dir_files = native.glob(["test/{}_data/**/*".format(suite_name)], allow_empty = True) _ct_test( shard_suite = Label("@rules_erlang//tools/shard_suite:shard_suite"), diff --git a/erlang_app.bzl b/erlang_app.bzl index d4853768..d8ef4421 100644 --- a/erlang_app.bzl +++ b/erlang_app.bzl @@ -97,14 +97,17 @@ def _erlang_app( only_srcs = native.glob( ["src/**/*.erl"], exclude = extra_srcs, + allow_empty = True, ) + extra_srcs private_hdrs = native.glob( ["src/**/*.hrl"], exclude = extra_hdrs, + allow_empty = True, ) public_hdrs = native.glob( ["include/**/*.hrl"], exclude = extra_hdrs, + allow_empty = True, ) + extra_hdrs srcs = only_srcs + private_hdrs + public_hdrs @@ -123,7 +126,7 @@ def _erlang_app( beam_files = [":beam_files" if not test else ":test_beam_files"] - if len(native.glob(["ebin/{}.app".format(app_name)])) == 0: + if len(native.glob(["ebin/{}.app".format(app_name)], allow_empty = True)) == 0: if not test: app_file( name = "app_file", @@ -135,7 +138,7 @@ def _erlang_app( app_env = app_env, app_extra_keys = app_extra_keys, extra_apps = extra_apps, - app_src = native.glob(["src/{}.app.src".format(app_name)]), + app_src = native.glob(["src/{}.app.src".format(app_name)], allow_empty = True), modules = beam_files, deps = deps + runtime_deps, dest = "ebin", @@ -146,9 +149,9 @@ def _erlang_app( else: app = "ebin/{}.app".format(app_name) - if len(native.glob(["ebin/{}.appup".format(app_name)])) > 0: + if len(native.glob(["ebin/{}.appup".format(app_name)], allow_empty = True)) > 0: appup = "ebin/{}.appup".format(app_name) - elif len(native.glob(["src/{}.appup".format(app_name)])) > 0: + elif len(native.glob(["src/{}.appup".format(app_name)], allow_empty = True)) > 0: if not test: copy_file( name = "appup", @@ -165,12 +168,14 @@ def _erlang_app( priv = native.glob( ["priv/**/*"], exclude = extra_priv, + allow_empty = True, ) + extra_priv if license_files == None: license_files = native.glob( ["LICENSE*"], exclude = extra_license_files, + allow_empty = True, ) + extra_license_files erlang_app_info( diff --git a/private/ct.bzl b/private/ct.bzl index 3f0fb966..3b150c63 100644 --- a/private/ct.bzl +++ b/private/ct.bzl @@ -63,7 +63,7 @@ def _impl(ctx): erl_libs_files = erl_libs_contents( ctx, - deps = flat_deps(ctx.attr.deps + ctx.attr.compiled_suites), + deps = flat_deps(ctx.attr.deps), ez_deps = ctx.files.ez_deps, dir = erl_libs_dir, ) @@ -179,7 +179,7 @@ set -x -no_auto_compile \\ -noinput \\ ${{FILTER}} \\ - -dir ebin {pa_args} \\ + -dir test {pa_args} \\ -logdir "{log_dir}" \\ -hidden \\ -sname {sname} ${{COVER_ARGS}} {extra_args} diff --git a/test/MODULE.bazel b/test/MODULE.bazel index a2c9cd76..96ddc805 100644 --- a/test/MODULE.bazel +++ b/test/MODULE.bazel @@ -5,12 +5,16 @@ module( bazel_dep( name = "platforms", - version = "0.0.7", + version = "0.0.11", ) bazel_dep( name = "rules_erlang", version = "3.0.0", ) +bazel_dep( + name = "rules_shell", + version = "0.6.1", +) local_path_override( module_name = "rules_erlang", path = "..", diff --git a/test/app_file/BUILD.bazel b/test/app_file/BUILD.bazel index 296fb559..30ae10d1 100644 --- a/test/app_file/BUILD.bazel +++ b/test/app_file/BUILD.bazel @@ -1,4 +1,5 @@ -load("@rules_erlang//private:app_file.bzl", "app_file") +load("@rules_erlang//:app_file.bzl", "app_file") +load("@rules_shell//shell:sh_test.bzl", "sh_test") app_file( name = "app_file", diff --git a/test/rules_erlang_compiler/test/dot_app_file_SUITE.erl b/test/rules_erlang_compiler/test/dot_app_file_SUITE.erl index 2bd49a45..31f4b37f 100644 --- a/test/rules_erlang_compiler/test/dot_app_file_SUITE.erl +++ b/test/rules_erlang_compiler/test/dot_app_file_SUITE.erl @@ -32,7 +32,8 @@ injects_modules(Config) -> "bazel-out/darwin-fastbuild/bin/deps_dir/basic/src/basic_acceptor.erl", "bazel-out/darwin-fastbuild/bin/deps_dir/basic/ebin/basic_acceptors_sup.beam", "bazel-out/darwin-fastbuild/bin/deps_dir/basic/src/basic_acceptors_sup.erl" - ] + ], + test_modules => [] }, Output = filename:join([DestDir, "basic", "ebin", "basic.app"]), diff --git a/test/shard_suite/BUILD.bazel b/test/shard_suite/BUILD.bazel index 81d1de36..b3d1b1e6 100644 --- a/test/shard_suite/BUILD.bazel +++ b/test/shard_suite/BUILD.bazel @@ -1,9 +1,9 @@ load( - "@rules_erlang//private:app_file.bzl", + "@rules_erlang//:app_file.bzl", "app_file", ) load( - "@rules_erlang//:erlang_bytecode2.bzl", + "@rules_erlang//:erlang_bytecode.bzl", "erlang_bytecode", ) load( @@ -69,29 +69,6 @@ erlang_app_info( beam = [":beam_files"], ) -erlang_app_info( - name = "test_erlang_app", - testonly = True, - srcs = ["@rules_erlang//tools/shard_suite:src/shard_suite.erl"], - app = ":app_file", - app_name = APP_NAME, - beam = [":test_beam_files"], -) - -xref() - -plt( - name = "base_plt", - apps = DEFAULT_PLT_APPS + [ - "crypto", - "common_test", - ], -) - -dialyze( - plt = ":base_plt", -) - erlang_bytecode( name = "test_example_suite_beam", testonly = True, @@ -128,12 +105,39 @@ erlang_bytecode( ], ) -eunit( - name = "eunit", - compiled_suites = [ +erlang_app_info( + name = "test_erlang_app", + testonly = True, + srcs = ["@rules_erlang//tools/shard_suite:src/shard_suite.erl"], + app = ":app_file", + app_name = APP_NAME, + beam = [":test_beam_files"], + test_beam = [ ":test_example_suite_beam", ":test_shard_suite_test_beam", ], +) + +xref() + +plt( + name = "base_plt", + apps = DEFAULT_PLT_APPS + [ + "crypto", + "common_test", + ], +) + +dialyze( + plt = ":base_plt", +) + +eunit( + name = "eunit", + eunit_mods = [ + "example_suite", + "shard_suite_test", + ], target = ":test_erlang_app", ) diff --git a/tools/rebar_config_to_erlc_opts/src/rebar_config_to_erlc_opts.erl b/tools/rebar_config_to_erlc_opts/src/rebar_config_to_erlc_opts.erl index baeb6a9f..41cdb602 100644 --- a/tools/rebar_config_to_erlc_opts/src/rebar_config_to_erlc_opts.erl +++ b/tools/rebar_config_to_erlc_opts/src/rebar_config_to_erlc_opts.erl @@ -21,13 +21,18 @@ erlc_opts(RebarConfig) -> lists:flatmap( fun (#{value := V, kind := erlc}) -> - [io_lib:format("+~s", [V])]; + [lists:flatten(io_lib:format("+~s", [V]))]; (_) -> [] end, ErlOpts ); _ -> - ["+debug_info"] + [] end, - lists:delete("+warnings_as_errors", lists:usort(["+deterministic", "+debug_info" | ErlcOpts])). + Defaults = + case lists:member("+no_debug_info", ErlcOpts) of + true -> ["+deterministic"]; + false -> ["+deterministic", "+debug_info"] + end, + lists:delete("+warnings_as_errors", lists:usort(Defaults ++ ErlcOpts)). From 55534786f6b32e8c63df12af694c0404fdc77d57 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 16:03:38 +0200 Subject: [PATCH 04/17] Drop legacy --noenable_bzlmod jobs The unit-test and test jobs ran bazelisk with --noenable_bzlmod, but the WORKSPACE files were removed in dc6c4b7 "Remove unused rules, tools, and examples". With Bazel 8 the previous setup failed at startup with: ERROR: Both --enable_bzlmod and --enable_workspace are disabled, but one of them must be enabled to fetch external dependencies. Adding --enable_workspace would not help because there is no WORKSPACE file to fall back to, and WORKSPACE support is being retired in Bazel 9. The unit-test-bzlmod and test-bzlmod jobs already cover the same OTP 25.3 and 26.2 matrix via bzlmod, so the legacy jobs are dropped and removed from the summary needs list. --- .github/workflows/test.yaml | 57 ------------------------------------- 1 file changed, 57 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3b7ab798..2c2d2faf 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -6,27 +6,6 @@ on: - develop pull_request: jobs: - unit-test: - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - otp: - - "25.3" - - "26.2" - steps: - - name: CHECKOUT - uses: actions/checkout@v7 - - name: CONFIGURE ERLANG - uses: erlef/setup-beam@v1 - with: - otp-version: ${{ matrix.otp }} - - name: UNIT TEST - run: | - ERLANG_HOME="$(dirname $(dirname $(which erl)))" - bazelisk test //... \ - --noenable_bzlmod \ - --color=yes unit-test-bzlmod: runs-on: ubuntu-24.04 strategy: @@ -47,40 +26,6 @@ jobs: ERLANG_HOME="$(dirname $(dirname $(which erl)))" bazelisk test //... \ --color=yes - test: - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - otp: - - "25.3" - - "26.2" - steps: - - name: CHECKOUT - uses: actions/checkout@v7 - - name: CONFIGURE ERLANG - uses: erlef/setup-beam@v1 - with: - otp-version: ${{ matrix.otp }} - - name: TEST - working-directory: test - run: | - ERLANG_HOME="$(dirname $(dirname $(which erl)))" - bazelisk test //... \ - --noenable_bzlmod \ - --color=yes - - name: RESOVLE TEST LOGS PATH - if: always() - working-directory: test - run: | - echo "LOGS_PATH=$(readlink -f bazel-testlogs)" >> $GITHUB_OUTPUT - id: resolve-test-logs-path - - name: CAPTURE TEST LOGS - if: always() - uses: actions/upload-artifact@v7 - with: - name: bazel-testlogs-${{matrix.otp}} - path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-bzlmod: runs-on: ubuntu-24.04 strategy: @@ -291,9 +236,7 @@ jobs: fi summary: needs: - - unit-test - unit-test-bzlmod - - test - test-bzlmod - test-bzlmod-macos - test-bzlmod-windows From ca9bd9c464d2288f3ffb0820d782487910e8e60a Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 16:25:19 +0200 Subject: [PATCH 05/17] Fix dialyze and root-level toolchain resolution under bzlmod Three independent fixes that were preventing the bzlmod test jobs from passing under Bazel 8.4.2: 1. private/ct.bzl: code_paths The helper was joining `dep.label.workspace_root` with short dirnames that already start with `..//`. In a bzlmod runfiles tree there is no `external/` directory at all, so the resulting path `external/rules_erlang+/../rules_erlang+/...` does not exist and dialyzer fails with "No such file, directory or application". Short paths already contain the correct runfiles prefix for files from other repositories, so the workspace_root should not be prepended. Affects //erl_attrs_to_json:dialyze, //rebar_config_to_erlc_opts:dialyze, //rules_erlang_compiler:dialyze. 2. tools/rules_erlang_compiler/src/types.hrl Commit 228b062 ("Fix testing support (ct, eunit)") made dot_app_file:render/3 destructure `test_modules` out of the target map but never updated the `target()` (and `target_extended()`) typespec, causing a dialyzer "Invalid type specification" error. 3. MODULE.bazel + repositories/erlang_config.bzl Since bfb48d7 ("Revert "Revert "default to internal"") the default value of the `erlang_internal_external` constraint setting is `erlang_internal`. That works for test/MODULE.bazel which uses internal_erlang_from_github_release, but the root MODULE.bazel uses external_erlang_from_path (auto-detected via _default_erlang_dict), so the host platform no longer satisfies the toolchain's `exec_compatible_with = ["//:erlang_external"]` requirement and resolution fails with "No matching toolchains found for types: //tools:toolchain_type" in unit-test-bzlmod. Generate an `erlang_external_platform` (parented on @platforms//host) in the @erlang_config repo and register it from the root MODULE.bazel via register_execution_platforms. This makes the external toolchain resolvable at the root without changing the new "default to internal" semantics that the test/ jobs rely on. --- MODULE.bazel | 4 ++++ private/ct.bzl | 5 +---- repositories/erlang_config.bzl | 8 ++++++++ tools/rules_erlang_compiler/src/types.hrl | 4 +++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index a5b2a055..0ff867a9 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -53,3 +53,7 @@ register_toolchains( "@erlang_config//external:toolchain_major_minor", "@gmake_config//:default_toolchain", ) + +register_execution_platforms( + "@erlang_config//:erlang_external_platform", +) diff --git a/private/ct.bzl b/private/ct.bzl index 3b150c63..9bc90344 100644 --- a/private/ct.bzl +++ b/private/ct.bzl @@ -39,10 +39,7 @@ def unique_short_dirnames(files): return dirs def code_paths(dep): - return [ - path_join(dep.label.workspace_root, d) if dep.label.workspace_root != "" else d - for d in unique_short_dirnames(dep[ErlangAppInfo].beam) - ] + return unique_short_dirnames(dep[ErlangAppInfo].beam) # Calling ctx.expand_location with short_paths=True gives # "Error in expand_location: Rule in 'private' cannot use private API" diff --git a/repositories/erlang_config.bzl b/repositories/erlang_config.bzl index 82d37049..c4200b91 100644 --- a/repositories/erlang_config.bzl +++ b/repositories/erlang_config.bzl @@ -267,6 +267,14 @@ constraint_value( constraint_setting = ":erlang_internal_external", ) +platform( + name = "erlang_external_platform", + constraint_values = [ + ":erlang_external", + ], + parents = ["@platforms//host"], +) + """ default_installation = erlang_installations[_DEFAULT_EXTERNAL_ERLANG_PACKAGE_NAME] diff --git a/tools/rules_erlang_compiler/src/types.hrl b/tools/rules_erlang_compiler/src/types.hrl index 2da385c8..514f290a 100644 --- a/tools/rules_erlang_compiler/src/types.hrl +++ b/tools/rules_erlang_compiler/src/types.hrl @@ -13,7 +13,8 @@ erlc_opts_file := string(), app_src := string() | null, srcs := [string()], - outs := [string()] + outs := [string()], + test_modules := [string()] }. -type target_extended() :: #{ @@ -22,6 +23,7 @@ app_src := string() | null, srcs := [string()], outs := [string()], + test_modules := [string()], compile_opts := [compile:option()], dest_dir := file:filename_all() }. From 80867f5e31ad3dcd6382c3133ab289a9e2c79786 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 16:36:26 +0200 Subject: [PATCH 06/17] Triage remaining CI jobs - Bump DEFAULT_ERLANG_VERSION from 26.0 to 28.1 (with updated sha256). OTP 26.0 source builds fail on the newer macOS 15 runner image, and pinning ancient releases for everyone is undesirable. 28.1 is the current stable release and builds cleanly on Linux and macOS. - test-bzlmod-macos: pin runs-on to macos-15 (was macos-latest, which has moved to macos-26 / Tahoe). macos-15 / Sequoia is the conservative, well-tested image; revisit once macos-26 has had more bake time. - test-bzlmod-windows: pin runs-on to windows-2025 (was windows-latest, whose new image is not yet recognised by erlef/setup-beam), and bump the matrix OTP to 28.1 to match the new default. - Drop test-host-erlang-change-detected entirely. The job depends on the :otp_version target and the erl_eval.bzl rule, both of which were removed in dc6c4b7 ("Remove unused rules, tools, and examples"). The job is also removed from the summary needs list. test-bzlmod-internal-erlang is left alone: it relies on a BuildBuddy API key that's available in repository secrets. --- .github/workflows/test.yaml | 40 +++---------------------------------- tools/erlang.bzl | 4 ++-- 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2c2d2faf..031a8864 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -59,7 +59,7 @@ jobs: name: bazel-testlogs-bzlmod-${{matrix.otp}} path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-bzlmod-macos: - runs-on: macos-latest + runs-on: macos-15 steps: - name: CHECKOUT uses: actions/checkout@v7 @@ -85,12 +85,12 @@ jobs: name: bazel-testlogs-bzlmod-macos path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-bzlmod-windows: - runs-on: windows-latest + runs-on: windows-2025 strategy: fail-fast: false matrix: otp: - - "25.3" + - "28.1" steps: - name: CHECKOUT uses: actions/checkout@v7 @@ -201,39 +201,6 @@ jobs: with: name: bazel-testlogs-bzlmod-coverage path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* - test-host-erlang-change-detected: - runs-on: ubuntu-24.04 - steps: - - name: CHECKOUT - uses: actions/checkout@v7 - - name: CONFIGURE ERLANG - uses: erlef/setup-beam@v1 - with: - otp-version: "25.0" - - name: BUILD - working-directory: test - id: before - run: | - bazelisk build :otp_version \ - --color=yes - echo "otp=$(cat bazel-bin/otp_version.txt)" >> $GITHUB_OUTPUT - - name: CONFIGURE ERLANG - uses: erlef/setup-beam@v1 - with: - otp-version: "24.3" - - name: BUILD - working-directory: test - id: after - run: | - bazelisk build :otp_version \ - --color=yes - echo "otp=$(cat bazel-bin/otp_version.txt)" >> $GITHUB_OUTPUT - - name: CHECK - run: | - set -x - if [[ "${{ steps.before.outputs.otp }}" == "${{ steps.after.outputs.otp }}" ]]; then - echo "Fail" - fi summary: needs: - unit-test-bzlmod @@ -242,7 +209,6 @@ jobs: - test-bzlmod-windows - test-bzlmod-internal-erlang - test-bzlmod-coverage - - test-host-erlang-change-detected runs-on: ubuntu-latest steps: - name: SUMMARY diff --git a/tools/erlang.bzl b/tools/erlang.bzl index 02ec15d6..06d6a537 100644 --- a/tools/erlang.bzl +++ b/tools/erlang.bzl @@ -8,8 +8,8 @@ load( "erlang_toolchain", ) -DEFAULT_ERLANG_VERSION = "26.0" -DEFAULT_ERLANG_SHA256 = "3ff3c53d7ef9a45b5720e95b8756269c1a1b58eb51accc992ca97522fdb234d4" +DEFAULT_ERLANG_VERSION = "28.1" +DEFAULT_ERLANG_SHA256 = "c7c6fe06a3bf0031187d4cb10d30e11de119b38bdba7cd277898f75d53bdb218" def erlang_toolchain_external(): erlang_constraint = Label("@rules_erlang//platforms:erlang_external") From 1ec390f33cb84e5db40cab114e3be1a0adc72a9b Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 17:13:50 +0200 Subject: [PATCH 07/17] Fix OTP-version-dependent test references after DEFAULT_ERLANG_VERSION bump After bumping DEFAULT_ERLANG_VERSION to 28.1, two test/ artifacts still referenced the old major version and broke analysis / runtime: - test/BUILD.bazel + test/.bazelrc: rename the `erlang_26_platform` alias (and the rbe --platforms flag pointing at it) to `erlang_28_platform`. `@erlang_config//:erlang__platform` targets are only generated for the OTP majors that are actually registered, so with the default internal Erlang now at 28.1 the alias' `actual` did not exist and `bazelisk test //...` failed during analysis for every job. - test/custom_vars/custom_var_test.sh: the test was checking that the OTP_VERSION toolchain variable matched `2[4-6]\.`, which only ever served to confirm the variable was populated. Relax the regex to `[0-9]+\.[0-9]+` so it accepts any modern OTP major (now exercising 25.3, 26.2, 28.1 and the host OTP on macOS). Validated with `cd test && bazelisk test //...`: all 13 tests pass. --- test/.bazelrc | 2 +- test/BUILD.bazel | 6 +++--- test/custom_vars/custom_var_test.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/.bazelrc b/test/.bazelrc index 1214f439..4c0bd78c 100644 --- a/test/.bazelrc +++ b/test/.bazelrc @@ -26,7 +26,7 @@ build:rbe --crosstool_top=@rbe//cc:toolchain build:rbe --extra_toolchains=@rbe//config:cc-toolchain build:rbe --host_platform=//:erlang_internal_platform -build:rbe --platforms=//:erlang_26_platform +build:rbe --platforms=//:erlang_28_platform build:rbe --host_cpu=k8 build:rbe --cpu=k8 diff --git a/test/BUILD.bazel b/test/BUILD.bazel index ad40cb44..8347fd2c 100644 --- a/test/BUILD.bazel +++ b/test/BUILD.bazel @@ -8,13 +8,13 @@ platform( parents = ["@rbe//config:platform"], ) -# define an alias for @erlang_config//:erlang_26_platform, so +# define an alias for @erlang_config//:erlang_28_platform, so # that it can be passed in the cli/.bazelrc and not encounter # the lack of mapping, as per # https://github.com/bazelbuild/bazel/issues/14852 alias( - name = "erlang_26_platform", - actual = "@erlang_config//:erlang_26_platform", + name = "erlang_28_platform", + actual = "@erlang_config//:erlang_28_platform", ) shell( diff --git a/test/custom_vars/custom_var_test.sh b/test/custom_vars/custom_var_test.sh index 04da552a..b7b3507f 100755 --- a/test/custom_vars/custom_var_test.sh +++ b/test/custom_vars/custom_var_test.sh @@ -2,4 +2,4 @@ set -ex cat custom_vars/custom_var -grep 'OTP_VERSION: 2[4-6]\.' custom_vars/custom_var +grep -E 'OTP_VERSION: [0-9]+\.[0-9]+' custom_vars/custom_var From 3a950b325f99730dcb6d97bec9c592268317d824 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 17:23:21 +0200 Subject: [PATCH 08/17] Override ImageOS for setup-beam on windows-2025 The windows-2025 runner image reports ImageOS=win25-vs2026, which erlef/setup-beam@v1 does not recognise. The action's supported set includes the bare 'win25', so pass it explicitly via the step's env. --- .github/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 031a8864..9843f762 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -96,6 +96,8 @@ jobs: uses: actions/checkout@v7 - name: CONFIGURE ERLANG uses: erlef/setup-beam@v1 + env: + ImageOS: win25 with: otp-version: ${{ matrix.otp }} - name: CONFIGURE BAZEL From f9998f2fd0d2eb61988f25a917b7a9fc9cd3e862 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 17:28:47 +0200 Subject: [PATCH 09/17] Fix unit-test-bzlmod and platforms version warning unit-test-bzlmod ran 'bazelisk test //...' at the repo root, but the root has no test targets (all live in test/, covered by the test-bzlmod job). Bazel exits non-zero with 'No test targets were found, yet testing was requested'. The job's purpose is to verify the root MODULE.bazel resolves and builds, so 'build' is the correct verb. Also bump the root bazel_dep on platforms from 0.0.10 to 0.0.11 to match test/MODULE.bazel and silence the --check_direct_dependencies warning during analysis. --- .github/workflows/test.yaml | 2 +- MODULE.bazel | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9843f762..234fba11 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -24,7 +24,7 @@ jobs: - name: UNIT TEST run: | ERLANG_HOME="$(dirname $(dirname $(which erl)))" - bazelisk test //... \ + bazelisk build //... \ --color=yes test-bzlmod: runs-on: ubuntu-24.04 diff --git a/MODULE.bazel b/MODULE.bazel index 0ff867a9..c3cd40de 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,7 +11,7 @@ bazel_dep( bazel_dep( name = "platforms", - version = "0.0.10", + version = "0.0.11", ) erlang_package = use_extension( From d98aa610a60cfe9d4f720bc597f75ef1118e795a Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 17:39:59 +0200 Subject: [PATCH 10/17] Drop windows job and wire BuildBuddy API key test-bzlmod-windows referenced --@rules_erlang//:ct_test_windows_logdir_drive_letter, which was deliberately removed (along with all other Windows-specific code paths) in 413df65 "drop windows". The job cannot be made to pass without reverting that decision, so remove it from the workflow and from the summary.needs list. test-bzlmod-internal-erlang was hitting BuildBuddy's anonymous-access deprecation (FAILED_PRECONDITION). Wire the BUILDBUDDY_API_KEY secret into the CONFIGURE BAZEL step and append --remote_header to the buildbuddy bazelrc config so authenticated traffic is used. --- .github/workflows/test.yaml | 51 +++---------------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 234fba11..4470160d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -84,53 +84,6 @@ jobs: with: name: bazel-testlogs-bzlmod-macos path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* - test-bzlmod-windows: - runs-on: windows-2025 - strategy: - fail-fast: false - matrix: - otp: - - "28.1" - steps: - - name: CHECKOUT - uses: actions/checkout@v7 - - name: CONFIGURE ERLANG - uses: erlef/setup-beam@v1 - env: - ImageOS: win25 - with: - otp-version: ${{ matrix.otp }} - - name: CONFIGURE BAZEL - working-directory: test - shell: bash - run: | - cat << EOF >> user.bazelrc - startup --output_user_root=C:/tmp - startup --windows_enable_symlinks - build --enable_runfiles - build --color=yes - build --@rules_erlang//:ct_test_windows_logdir_drive_letter=z - build --jobs=1 - EOF - - name: TEST - working-directory: test - shell: cmd - run: | - bazelisk test //... - - name: RESOVLE TEST LOGS PATH - if: always() - working-directory: test - shell: bash - run: | - LOGS_TAR=$PWD/logs.tar - cd bazel-testlogs - tar -cf $LOGS_TAR * - - name: CAPTURE TEST LOGS - if: always() - uses: actions/upload-artifact@v7 - with: - name: bazel-testlogs-bzlmod-windows-${{matrix.otp}} - path: test/logs.tar test-bzlmod-internal-erlang: runs-on: ubuntu-24.04 steps: @@ -138,10 +91,13 @@ jobs: uses: actions/checkout@v7 - name: CONFIGURE BAZEL working-directory: test + env: + BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} run: | cat << EOF >> user.bazelrc build:buildbuddy --remote_download_minimal build:buildbuddy --color=yes + build:buildbuddy --remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY EOF - name: BUILD working-directory: test @@ -208,7 +164,6 @@ jobs: - unit-test-bzlmod - test-bzlmod - test-bzlmod-macos - - test-bzlmod-windows - test-bzlmod-internal-erlang - test-bzlmod-coverage runs-on: ubuntu-latest From 1d8a98a3aa245b1c4a5baf1f7f107313303bef78 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 18:00:35 +0200 Subject: [PATCH 11/17] Skip test-bzlmod-internal-erlang when BUILDBUDDY_API_KEY is unset BuildBuddy no longer accepts anonymous traffic, so the job is useless without the API key. Gate it with a job-level 'if' so forks and any contexts where the secret is unavailable don't fail CI. Relax the summary gate to accept 'skipped' alongside 'success' so a skipped internal-erlang doesn't cascade into a red summary. --- .github/workflows/test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4470160d..ceae7e22 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -86,6 +86,7 @@ jobs: path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* test-bzlmod-internal-erlang: runs-on: ubuntu-24.04 + if: ${{ secrets.BUILDBUDDY_API_KEY != '' }} steps: - name: CHECKOUT uses: actions/checkout@v7 @@ -170,6 +171,6 @@ jobs: steps: - name: SUMMARY run: | - cat << 'EOF' | jq -e 'map(.result == "success") | all(.)' + cat << 'EOF' | jq -e 'map(.result == "success" or .result == "skipped") | all(.)' ${{ toJson(needs) }} EOF From fcc21bdd34899b2b23256755256b956613e8e2ee Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 18:06:38 +0200 Subject: [PATCH 12/17] Use guard job for BuildBuddy secret check; restore Examples workflow The 'secrets' context is not allowed in job-level 'if:' (only github, needs, vars, inputs are). The previous attempt produced a workflow syntax error that aborted the entire Test run. Replace the inline secrets check with a tiny check-buildbuddy-secret job that exports 'has-key' as a job output, then gate test-bzlmod-internal-erlang on 'needs.check-buildbuddy-secret.outputs.has-key == true'. Examples workflow was stuck queued forever because ubuntu-20.04 was retired from GitHub-hosted runners. Bump to ubuntu-24.04 to match the rest of the workflows. --- .github/workflows/examples.yaml | 2 +- .github/workflows/test.yaml | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index 931b34d2..f4bdf1a9 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -9,7 +9,7 @@ on: pull_request: jobs: examples-basic: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ceae7e22..8b6c9b00 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -84,9 +84,24 @@ jobs: with: name: bazel-testlogs-bzlmod-macos path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* + check-buildbuddy-secret: + runs-on: ubuntu-24.04 + outputs: + has-key: ${{ steps.check.outputs.has-key }} + steps: + - id: check + env: + BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} + run: | + if [ -n "$BUILDBUDDY_API_KEY" ]; then + echo "has-key=true" >> $GITHUB_OUTPUT + else + echo "has-key=false" >> $GITHUB_OUTPUT + fi test-bzlmod-internal-erlang: runs-on: ubuntu-24.04 - if: ${{ secrets.BUILDBUDDY_API_KEY != '' }} + needs: check-buildbuddy-secret + if: needs.check-buildbuddy-secret.outputs.has-key == 'true' steps: - name: CHECKOUT uses: actions/checkout@v7 From 4696228626b05b01ab25d729af65484316126000 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Tue, 23 Jun 2026 21:48:48 +0200 Subject: [PATCH 13/17] Point Examples workflow at examples/umbrella examples/basic was deleted in dc6c4b7 'Remove unused rules, tools, and examples'. The surviving example is examples/umbrella, which has eunit and ct_test targets. Update the workflow path, job name, and artifact name accordingly. --- .github/workflows/examples.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index f4bdf1a9..ee614616 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -8,7 +8,7 @@ on: - bump-rbe pull_request: jobs: - examples-basic: + examples-umbrella: runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -23,13 +23,13 @@ jobs: with: otp-version: ${{ matrix.otp }} - name: TEST - working-directory: examples/basic + working-directory: examples/umbrella run: | bazelisk test //... \ --color=yes - name: RESOVLE TEST LOGS PATH if: always() - working-directory: examples/basic + working-directory: examples/umbrella run: | echo "LOGS_PATH=$(readlink -f bazel-testlogs)" >> $GITHUB_OUTPUT id: resolve-test-logs-path @@ -37,5 +37,5 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: bazel-testlogs-examples-basic-${{matrix.otp}} + name: bazel-testlogs-examples-umbrella-${{matrix.otp}} path: ${{ steps.resolve-test-logs-path.outputs.LOGS_PATH }}/* From e70ed5aacead1535ad6f885f17f644703ba9ae04 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Wed, 24 Jun 2026 03:50:21 +0200 Subject: [PATCH 14/17] extract_app: namespace .beam/.app outputs by target name Previously every extract_app target in a package declared its outputs under /ebin/. That made it impossible to have two extract_app targets (e.g. a prod :erlang_app and a :test_erlang_app) in the same package, because both would race to declare the same ebin/.{beam,app} outputs and Bazel would reject the analysis with a duplicate-action error. Namespace only the .beam and .app outputs under /ebin/. The header and priv outputs are left at their natural location: the package-prefix-stripping helper additional_file_dest_relative_path() in private/util.bzl expects them there, and shifting them would double the package segment when those files are later placed into a runtime erl_libs tree (which manifested as relx failing to find its priv/templates/* at release-assembly time). --- private/extract_app.bzl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/private/extract_app.bzl b/private/extract_app.bzl index 67d50543..a3456a8b 100644 --- a/private/extract_app.bzl +++ b/private/extract_app.bzl @@ -18,6 +18,15 @@ def _impl(ctx): public_hdrs = app_info.source_info.public_hdrs private_hdrs = app_info.source_info.private_hdrs + # Only .beam and .app outputs collide between same-package + # extract_app targets (e.g. a prod :erlang_app and a + # :test_erlang_app extracting the same app), so namespace just + # those under the target name. Header and priv outputs stay at + # their natural location so that consumers stripping the package + # prefix via additional_file_dest_relative_path (e.g. for hex + # packages that ship priv files like relx) keep working. + beam_prefix = ctx.label.name + out_base = None if ctx.attr.copy_headers: for out in app_info.outs: @@ -38,6 +47,7 @@ def _impl(ctx): if not ctx.attr.test and is_test_module: continue dest = ctx.actions.declare_file(path_join( + beam_prefix, "ebin", out.basename, )) From 5d3d945e954aa96ec80ad2eb3fae9cf89cc0b916 Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Wed, 24 Jun 2026 11:56:20 +0200 Subject: [PATCH 15/17] umbrella example: use ct_suite for umbrella_smoke_SUITE The umbrella_smoke_SUITE ct_test invocation never worked since it was introduced: ct_test() expects the suite beam to already be compiled into apps/greeter_web/test/, but no rule was producing that beam, so ct_run -dir test would always fail with 'Suite ... not found'. Switching to ct_suite() makes the macro emit an erlang_bytecode target that compiles test/umbrella_smoke_SUITE.erl into the expected test/ subdirectory and threads it through as compiled_suites. ct_suite() also globs test/_data/** on its own and injects :test_erlang_app as a dep, so the redundant data= line is dropped. --- examples/umbrella/apps/greeter_web/BUILD.bazel | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/umbrella/apps/greeter_web/BUILD.bazel b/examples/umbrella/apps/greeter_web/BUILD.bazel index 5fe1f36f..732af482 100644 --- a/examples/umbrella/apps/greeter_web/BUILD.bazel +++ b/examples/umbrella/apps/greeter_web/BUILD.bazel @@ -1,5 +1,5 @@ load("@rules_erlang//:compile_many.bzl", "compile_many") -load("@rules_erlang//:ct.bzl", "ct_test") +load("@rules_erlang//:ct.bzl", "ct_suite") load("@rules_erlang//:dialyze.bzl", "DEFAULT_PLT_APPS", "dialyze", "plt") load("@rules_erlang//:erlang_app_sources.bzl", "erlang_app_sources") load("@rules_erlang//:erlc_opts_file.bzl", "erlc_opts_file") @@ -128,9 +128,8 @@ eunit( target = ":test_erlang_app", ) -ct_test( +ct_suite( name = "umbrella_smoke_SUITE", - data = [":test_erlang_app"] + glob(["test/umbrella_smoke_SUITE_data/**/*"]), suite_name = "umbrella_smoke_SUITE", size = "small", ) From fc1d7ef3f8ac092d31975f1aec1890e821be289b Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Wed, 24 Jun 2026 12:19:35 +0200 Subject: [PATCH 16/17] umbrella example: include eunit/common_test in dialyze PLT DEFAULT_PLT_APPS only covers erts/kernel/stdlib. The umbrella's :test_erlang_app targets pull in test sources (greeter_tests.erl, greeter_web_tests.erl) that call eunit:test/1, so dialyzer reports 'Unknown functions: eunit:test/1' and exits with warnings. Extend each app's plt() apps list with eunit and common_test so the analysis can resolve test-framework calls. --- examples/umbrella/apps/greeter/BUILD.bazel | 2 +- examples/umbrella/apps/greeter_web/BUILD.bazel | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/umbrella/apps/greeter/BUILD.bazel b/examples/umbrella/apps/greeter/BUILD.bazel index ece562ab..b32a9b52 100644 --- a/examples/umbrella/apps/greeter/BUILD.bazel +++ b/examples/umbrella/apps/greeter/BUILD.bazel @@ -104,7 +104,7 @@ xref( plt( name = "deps_plt", - apps = DEFAULT_PLT_APPS, + apps = DEFAULT_PLT_APPS + ["eunit", "common_test"], for_target = ":test_erlang_app", ) diff --git a/examples/umbrella/apps/greeter_web/BUILD.bazel b/examples/umbrella/apps/greeter_web/BUILD.bazel index 732af482..23ab3c57 100644 --- a/examples/umbrella/apps/greeter_web/BUILD.bazel +++ b/examples/umbrella/apps/greeter_web/BUILD.bazel @@ -113,7 +113,7 @@ xref( plt( name = "deps_plt", - apps = DEFAULT_PLT_APPS, + apps = DEFAULT_PLT_APPS + ["eunit", "common_test"], for_target = ":test_erlang_app", ) From e753ad8d71769d41cddc4af0f85c8d9868206b6e Mon Sep 17 00:00:00 2001 From: Sebastian Weddmark Olsson Date: Wed, 24 Jun 2026 12:24:38 +0200 Subject: [PATCH 17/17] Test workflow: run summary even when a needed job is skipped By default GitHub propagates 'skipped' through job dependencies, so the summary job was being auto-skipped whenever test-bzlmod-internal-erlang is skipped on forks/branches without BUILDBUDDY_API_KEY. That defeats the summary's gating role. Add 'if: ${{ !cancelled() }}' so the summary runs on success / failure / skipped (but not on cancellation), letting the existing jq check ('success' or 'skipped') decide pass/fail. --- .github/workflows/test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8b6c9b00..5e446d1d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -182,6 +182,7 @@ jobs: - test-bzlmod-macos - test-bzlmod-internal-erlang - test-bzlmod-coverage + if: ${{ !cancelled() }} runs-on: ubuntu-latest steps: - name: SUMMARY