bazel icon indicating copy to clipboard operation
bazel copied to clipboard

Cannot pass envvar to app launched by bazel run without invalidating repo and triggering rebuild

Open peakschris opened this issue 6 months ago • 9 comments

Description of the bug:

I can't find any effective way to pass an environment variable, whose value may change, to an application launched by bazel run, without invalidating the bazel cache (seems to be repo cache but may be others) and triggering a large rebuild.

The current approach is (windows):

set MYVAR=123
bazel run //:myapp

Since there is no way to sanitize the repo_env (https://github.com/bazelbuild/bazel/issues/10996), it's impossible for me to prevent MYVAR from invalidating the repo cache. There is neither a way to sanitize all variables or sanitize specific variables.

As a workaround, if I know upfront that MYVAR may be set at some point, i can add common --repo_env=MYVAR=invalid_value to a .bazelrc file, but in many cases the complete set of envvars is not known.

This also relates to: https://github.com/bazelbuild/bazel/issues/20187

I think the cleanest way to resolve this without the variables interfering with any of bazel's client environment would be to support a --run_env option that works in the same way as --test_env.

Which category does this issue belong to?

Core

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

No response

Which operating system are you running Bazel on?

windows

What is the output of bazel info release?

release 8.2.1

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse HEAD ?


If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

No response

Have you found anything relevant by searching the web?

No response

Any other information, logs, or outputs that you want to share?

No response

peakschris avatar Jun 07 '25 19:06 peakschris

A general --run_env flag seems useful, but wouldn't the invalidation you see only happen for those env vars that any repo rule explicitly depends on? In that case, what would the .bazelrc entry do to prevent this?

fmeum avatar Jun 07 '25 19:06 fmeum

@fmeum thank you that pointer helped me to find that one of our repository_rules has local=True and configure=True, which I think then leads to bazel re-evaluating on envvar changes.

After fixing this, the repository rules still rerun on rebuild (but less often). And I'm still seeing c++ recompilations when I bazel build with a standard shell environment after running bazel build with a sanitized environment. Is it possible that the msvc toolchain or something else in Bazel is reading environment variables? Is there some way to see a list of vars that my configuration is reading?

peakschris avatar Jun 07 '25 20:06 peakschris

One extra clue is that on rebuild bazel first prints: WARNING: Build option --python_path has changed, discarding analysis cache

I don't have python_path set in .bazelrc or command line or as envvar. But I do have python on the unsanitized path. Python is not on the sanitized path.

peakschris avatar Jun 07 '25 20:06 peakschris

@fmeum thank you that pointer helped me to find that one of our repository_rules has local=True and configure=True, which I think then leads to bazel re-evaluating on envvar changes.

configure = True doesn't have anything to do with env vars and local = True results in invalidation on server restarts. Env var changes may cause those (say JAVA_HOME), but most don't.

After fixing this, the repository rules still rerun on rebuild (but less often). And I'm still seeing c++ recompilations when I bazel build with a standard shell environment after running bazel build with a sanitized environment. Is it possible that the msvc toolchain or something else in Bazel is reading environment variables? Is there some way to see a list of vars that my configuration is reading?

Recompilation should only occur when actions pick up the env vars, not just repo rules. The best way to debug that would be via -s or the execution log.

fmeum avatar Jun 08 '25 08:06 fmeum

One extra clue is that on rebuild bazel first prints: WARNING: Build option --python_path has changed, discarding analysis cache

I don't have python_path set in .bazelrc or command line or as envvar. But I do have python on the unsanitized path. Python is not on the sanitized path.

This is weird, repo rules don't influence flags, so this is probably something else entirely. What do you see when running with --announce_rc?

fmeum avatar Jun 08 '25 08:06 fmeum

This is weird, repo rules don't influence flags, so this is probably something else entirely. What do you see when running with --announce_rc?

Build events contains this:

"unstructuredCommandLine":{"args":["query","--startup_time\u003d261","--command_wait_time\u003d0","--binary_path\u003dC:\\Users\\browchri.PLM\\AppData\\Local\\bazelisk\\downloads\\sha256\\94d3463f990601c2561a2904c0622205c51e4bc100783c77d6d13e720a540cb8\\bin\\bazel.exe","--rc_source\u003dclient","--default_override\u003d0:common\u003d--isatty\u003d0","--default_override\u003d0:common\u003d--terminal_columns\u003d80","--default_override\u003d0:build\u003d--python_path\u003dt:/wntx64/python/3.11/python.exe","--rc_source\u003dc:\\programdata\\bazel.bazelrc",

It seems to be due to this code, I can't see a way to disable it. https://github.com/bazelbuild/bazel/blob/7b9a33fddb59f67f4d100c7a6df5a911376f00d3/src/main/cpp/blaze_util_windows.cc#L1497

I'm debugging the recompilations, which are still occurring even without the above.

peakschris avatar Jun 08 '25 11:06 peakschris

It seems to be due to this code, I can't see a way to disable it.

And just to add, bazel is searching for a local python on my PATH even though i have these set. Arguably, this should not happen.

common --incompatible_use_python_toolchains common --incompatible_strict_action_env

peakschris avatar Jun 08 '25 12:06 peakschris

https://github.com/bazel-contrib/rules_python/blob/049866442fee7bb54fcb1a09e920953a0666e4b3/python/private/py_executable.bzl#L1228 mentions am issue that aims to drop this flag entirely - that seems like the best fix.

fmeum avatar Jun 08 '25 12:06 fmeum

You mentioned Windows, so this may not work for you, but on Unix-y platforms you can pass environment variables to bazel run while preventing them from being seen by repo rules (even when they are declared inputs of the repo rule) with: bazel run --run_under=MYVAR=123 ...

pcjanzen avatar Jun 08 '25 15:06 pcjanzen

Nevermind, --run_env does exist in Bazel 8: https://github.com/bazelbuild/bazel/pull/24068. This can be closed, I guess?

fmeum avatar Jun 27 '25 17:06 fmeum

Closing.

iancha1992 avatar Jun 27 '25 18:06 iancha1992