feat(runner): pre/post commands with separate env - #39
Open
tsvikas wants to merge 8 commits into
Open
Conversation
Extra env vars passed via Runner.env were logged to stderr but never written to run_info.json (or W&B config), so reproducing a run from the JSON alone was incomplete. Add meta/env as a dict; None values (vars explicitly unset for the subprocess) survive as JSON null. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reproducibility additions to the recorded run config: - meta/cwd, meta/user — capture working directory and invoking user - param_source/<k> — mirrors Runner.param_sources so the JSON shows whether each param value came from cli/default/fixed/prompt/override Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
For env vars (tokens, API keys) the subprocess needs but that should never appear in logs or recorded config: secret_env values pass through to the subprocess unchanged, but render as *** in the Env: log line and are stored as "***" in meta/env so the key list is still recorded. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…table Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New Command dataclass for auxiliary subprocesses run alongside the main
command. Output is streamed to the terminal and saved to per-command log
files (<phase>_<name>{,_stdout,_stderr}.log), which are also uploaded to
backends as text artifacts so the recorded run shows what setup or
teardown actually did.
- pre_commands run after the code snapshot but before the main subprocess.
A non-zero exit aborts the run; main and post commands are skipped, but
the backends are still finalized cleanly with the failing exit code.
- post_commands run after the main subprocess. Failures are warned but
never change the run outcome (consistent with the never-fail post-run
philosophy). Skipped only if a pre-command failed.
Also extracts _build_run_env() so aux commands inherit the same env
(including secret_env) as the main subprocess.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Command gains an env field (dict[str, str | None]); aux commands now build their own env from os.environ + cmd.env. They no longer inherit Runner.env / Runner.secret_env, so e.g. CUDA_VISIBLE_DEVICES set for the main subprocess doesn't leak into uv-pip-list-style snapshots. - \$output is interpolated in command tokens and env values (same syntax as Param value=). - Pre/post commands run in declared list order (already true; documented). - Updated examples/run_example.py with pre 'uv sync -v' and post 'uv pip list' to demonstrate the canonical use case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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.
Summary
Add
Runner.pre_commandsandRunner.post_commandsfor auxiliary subprocesses run alongside the main command. Use cases: build steps before training, environment snapshots (uv pip list) for reproducibility, post-run summaries.New
Command(name, command, env={})dataclass:nameshows up in log filenames and the W&B artifact key.commandis split viashlex(str) or used as-is (list).envis the command's own env (None to unset). Aux commands do not inheritRunner.env/Runner.secret_env— they get a clean env fromos.environplus per-command overrides. This avoidsCUDA_VISIBLE_DEVICESetc. leaking intouv pip list-style snapshots.$outputis interpolated in both command tokens and env values.Behavior:
<phase>_<name>.log(combined),<phase>_<name>_stdout.log, and<phase>_<name>_stderr.login the run's output directory; uploaded to backends as text artifacts.--dry-run(logged but not executed).Also extracted
Runner._build_run_env()fromexecute()for clarity (still used by main command).examples/run_example.pyupdated with preuv sync -vand postuv pip list.Test plan
uv run pytest(228 tests; 9 new for aux commands: pre runs/writes logs, pre failure skips main, post runs after main, post failure doesn't abort, post skipped when pre fails, name validation,$outputinterpolation in tokens + env, separate env from main, list-order execution)uv run ruff check . && uv run mypy🤖 Generated with Claude Code