Repository: skypilot-org/skypilot
Pull request: Allow setting the workdir using environment variables
<!-- Describe the changes in this PR -->
Allows the workdir to be configured using environment variables.

Closes #3271 


<!-- Describe the tests ran -->
<!-- Unit tests (tests/test_*.py) are part of GitHub CI; below are tests that launch on the cloud. -->

Tested (run the relevant ones):

- [x] Code formatting: `bash format.sh`
- [ ] Any manual or new tests for this PR (please specify below)
- [ ] All smoke tests: `pytest tests/test_smoke.py` 
- [ ] Relevant individual smoke tests: `pytest tests/test_smoke.py::test_fill_in_the_name` 
- [ ] Backward compatibility tests: `conda deactivate; bash -i tests/backward_compatibility_tests.sh`


Problem statement:
Allow setting the `workdir` using environment variables
For situations when the working directory is not known in advance (e.g., on remote machines), it would be helpful to be able to dynamically populate the `workdir` value using an environment variable using the following syntax:

```yaml
envs:
  MY_WORKDIR: "some/path/"

workfir: ${MY_WORKDIR}
```

Hints from issue discussion:
This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 10 days.
This issue was closed because it has been stalled for 10 days with no activity.

Commit message: Format

Patch to review:
diff --git a/sky/task.py b/sky/task.py
index cf26e13717a..cebc616dc6d 100644
--- a/sky/task.py
+++ b/sky/task.py
@@ -393,6 +393,11 @@ def from_yaml_config(
             config['service'] = _fill_in_env_vars(config['service'],
                                                   config.get('envs', {}))
 
+        # Fill in any Task.envs into workdir
+        if config.get('workdir') is not None:
+            config['workdir'] = _fill_in_env_vars(config['workdir'],
+                                                  config.get('envs', {}))
+
         task = Task(
             config.pop('name', None),
             run=config.pop('run', None),
diff --git a/tests/test_yaml_parser.py b/tests/test_yaml_parser.py
index 1453cfe1620..752f86cf79e 100644
--- a/tests/test_yaml_parser.py
+++ b/tests/test_yaml_parser.py
@@ -146,3 +146,14 @@ def test_invalid_empty_envs(tmp_path):
     with pytest.raises(ValueError) as e:
         Task.from_yaml(config_path)
     assert 'Environment variable \'env_key2\' is None.' in e.value.args[0]
+
+
+def test_replace_envs_in_path(tmpdir, tmp_path):
+    config_path = _create_config_file(
+        textwrap.dedent(f"""\
+            envs:
+                env_key1: {tmpdir}
+            workdir: $env_key1
+            """), tmp_path)
+    task = Task.from_yaml(config_path)
+    assert task.workdir == tmpdir


Code review comments:
diff_hunk: @@ -146,3 +146,14 @@ def test_invalid_empty_envs(tmp_path):
     with pytest.raises(ValueError) as e:
         Task.from_yaml(config_path)
     assert 'Environment variable \'env_key2\' is None.' in e.value.args[0]
+
+
+def test_replace_envs_in_path(tmpdir, tmp_path):
path: tests/test_yaml_parser.py
text: @user1:
nit - rename?
```suggestion
def test_replace_envs_in_workdir(tmpdir, tmp_path):
```