diff --git a/.github/e2e-stack/secrets_to_env.py b/.github/e2e-stack/secrets_to_env.py index 7913b25918b..691c10203bf 100644 --- a/.github/e2e-stack/secrets_to_env.py +++ b/.github/e2e-stack/secrets_to_env.py @@ -9,6 +9,7 @@ from pydantic import TypeAdapter, ValidationError secrets_adapter: Final[TypeAdapter[dict[str, str]]] = TypeAdapter(dict[str, str]) ENV_NAME: Final = re.compile(r"[A-Za-z_][A-Za-z0-9_]*") MIN_MASKED_LENGTH: Final = 8 +ACTIONS_RUNNER_FLAG: Final = "GITHUB_ACTIONS" def main() -> int: @@ -30,10 +31,15 @@ def main() -> int: f"these names or values cannot be represented in both bash and dotenv: {' '.join(sorted(unusable))}\n" ) return 1 - for value in secrets.values(): - if len(value) >= MIN_MASKED_LENGTH: - _ = sys.stdout.write(f"::add-mask::{value.replace('%', '%25')}\n") - sys.stdout.flush() + if os.environ.get(ACTIONS_RUNNER_FLAG) == "true": + _ = sys.stdout.write( + "".join( + f"::add-mask::{value.replace('%', '%25')}\n" + for value in secrets.values() + if len(value) >= MIN_MASKED_LENGTH + ) + ) + sys.stdout.flush() lines: Final = tuple(f"{key}='{value}'" for key, value in secrets.items() if value) try: with os.fdopen(os.open(env_path, os.O_WRONLY | os.O_APPEND | os.O_CREAT | os.O_NOFOLLOW, 0o600), "w") as handle: diff --git a/tests/code_coverage_tests/test_e2e_changed_gate.py b/tests/code_coverage_tests/test_e2e_changed_gate.py index 2b37ab14e7f..758d579f67d 100644 --- a/tests/code_coverage_tests/test_e2e_changed_gate.py +++ b/tests/code_coverage_tests/test_e2e_changed_gate.py @@ -106,10 +106,11 @@ def test_short_values_are_written_without_masking_every_digit_in_the_log(tmp_pat env_path: Final = tmp_path / ".env" result: Final = subprocess.run( - [sys.executable, str(SECRETS_TO_ENV), str(env_path)], + [sys.executable, "-I", str(SECRETS_TO_ENV), str(env_path)], input='{"FLAG": "1", "API_KEY": "sk-0123456789abcdef"}', capture_output=True, text=True, + env={**os.environ, "GITHUB_ACTIONS": "true"}, ) assert result.returncode == 0, result.stderr @@ -117,6 +118,24 @@ def test_short_values_are_written_without_masking_every_digit_in_the_log(tmp_pat assert env_path.read_text() == "FLAG='1'\nAPI_KEY='sk-0123456789abcdef'\n" +def test_outside_actions_no_value_is_printed(tmp_path: Path) -> None: + env_path: Final = tmp_path / ".env" + local_env: Final = {key: value for key, value in os.environ.items() if key != "GITHUB_ACTIONS"} + + result: Final = subprocess.run( + [sys.executable, "-I", str(SECRETS_TO_ENV), str(env_path)], + input='{"FLAG": "1", "API_KEY": "sk-0123456789abcdef"}', + capture_output=True, + text=True, + env=local_env, + ) + + assert result.returncode == 0, result.stderr + assert result.stdout == "" + assert "sk-0123456789abcdef" not in result.stderr + assert env_path.read_text() == "FLAG='1'\nAPI_KEY='sk-0123456789abcdef'\n" + + def redact_output(tmp_path: Path, values: tuple[str, ...], text: str) -> tuple[subprocess.CompletedProcess[str], Path]: env_path: Final = tmp_path / ".env" _ = env_path.write_text("".join(f"{name}='{value}'\n" for name, value in zip(("A", "B", "C"), values)))