2828from polyaxon ._flow import V1Operation , V1RunPending
2929from polyaxon ._managers .git import GitConfigManager
3030from polyaxon ._managers .run import RunConfigManager
31- from polyaxon ._polyaxonfile import check_polyaxonfile
31+ from polyaxon ._polyaxonfile import check_polyaxonfile , CompiledOperationSpecification
3232from polyaxon ._runner .kinds import RunnerKind
3333from polyaxon ._schemas .lifecycle import ManagedBy
3434from polyaxon ._utils import cache
@@ -161,14 +161,31 @@ def start_run_shell(run_uuid: str):
161161 }
162162 ctx .invoke (run_shell )
163163
164- def upload_run (run_uuid : str ):
164+ def upload_run (run_uuid : str , path_from : str , path_to : str ):
165165 ctx .obj = {
166166 "project" : "{}/{}" .format (owner_team , project_name ),
167167 "run_uuid" : run_uuid ,
168168 }
169169 ctx .invoke (
170- run_upload , path_to = upload_to , path_from = upload_from , sync_failure = True
170+ run_upload ,
171+ path_to = path_to ,
172+ path_from = path_from ,
173+ sync_failure = True ,
171174 )
175+
176+ def upload_mounts (run_uuid : str ):
177+ if upload :
178+ upload_run (
179+ build_uuid or run_instance .uuid ,
180+ path_to = upload_to ,
181+ path_from = upload_from ,
182+ )
183+
184+ compiled_spec = CompiledOperationSpecification .read (run_instance .content )
185+ mounts = compiled_spec .get_resolved_mount ()
186+ for mount in mounts :
187+ upload_run (run_uuid , path_from = mount .path_from , path_to = mount .path_to )
188+
172189 if approve_after and approve_after > 0 :
173190 Printer .print (f"Waiting { approve_after } s to approve the run..." )
174191 time .sleep (approve_after )
@@ -184,10 +201,12 @@ def upload_run(run_uuid: str):
184201 upload_to = upload_to or DEFAULT_UPLOADS_PATH
185202 run_meta_info = run_meta_info or {}
186203 run_meta_info [META_UPLOAD_ARTIFACTS ] = upload_to
204+
205+ is_uploading = upload or op_spec .has_mount ()
187206 run_instance = create_run (
188207 managed_by = managed_by ,
189208 meta_info = run_meta_info ,
190- pending = V1RunPending .UPLOAD if upload else None ,
209+ pending = V1RunPending .UPLOAD if is_uploading else None ,
191210 )
192211 if not run_instance :
193212 return
@@ -200,8 +219,8 @@ def upload_run(run_uuid: str):
200219 build_name = run_instance .settings .build .get ("name" )
201220 runs_to_watch .insert (0 , RunWatchSpec (build_uuid , build_name ))
202221
203- if upload :
204- upload_run (build_uuid or run_instance .uuid )
222+ if is_uploading :
223+ upload_mounts (build_uuid or run_instance .uuid )
205224
206225 if local :
207226 for instance in runs_to_watch :
@@ -277,8 +296,20 @@ def upload_run(run_uuid: str):
277296 "-u" ,
278297 is_flag = True ,
279298 default = False ,
280- help = "To upload the working dir to run's artifacts path "
281- "as an init context before scheduling the run." ,
299+ help = "Upload the current working directory to run's artifacts path "
300+ "as an init context before scheduling the run. "
301+ "Uploads to 'uploads/' by default." ,
302+ )
303+ @click .option (
304+ "--mount" ,
305+ "-m" ,
306+ "mounts" ,
307+ multiple = True ,
308+ type = str ,
309+ help = "Mount local paths to run artifacts. "
310+ "Syntax: './src:dest' or './src' (defaults to 'uploads/' destination). "
311+ "Can be specified multiple times. "
312+ "Examples: -m ./code -m ./data:datasets -m ./models:models" ,
282313)
283314@click .option (
284315 "--upload-from" ,
@@ -437,6 +468,7 @@ def run(
437468 shell ,
438469 log ,
439470 upload ,
471+ mounts ,
440472 upload_from ,
441473 upload_to ,
442474 watch ,
@@ -498,21 +530,20 @@ def run(
498530 $ polyaxon run -pm path/to/my-component.py:componentA
499531
500532
501- Uploading from everything in the current folder to the default uploads path
533+ Uploading current folder to the default uploads path
502534
503535 \b
504536 $ polyaxon run ... -u
505537
506-
507- Uploading from everything in the current folder to a custom path, e.g. code
538+ Uploading from a subfolder to a custom path
508539
509540 \b
510- $ polyaxon run ... -u-to code
541+ $ polyaxon run ... -u -u-from ./code -u -to code
511542
512- Uploading from everything from a sub-folder, e.g. ./code to the a custom path, e.g. new-code
543+ Mounting multiple paths using -m
513544
514545 \b
515- $ polyaxon run ... -u-from ./code -u-to new-code
546+ $ polyaxon run ... -m ./src: code -m ./data:datasets -m ./models
516547 """
517548 if log and shell :
518549 Printer .error (
@@ -590,6 +621,13 @@ def run(
590621 owner , team , project_name = get_project_or_local (project , is_cli = True )
591622 tags = validate_tags (tags , validate_yaml = True )
592623
624+ # Handle CLI uploads - merge with polyaxonfile mount section
625+ cli_mounts = list (mounts ) if mounts else []
626+
627+ if cli_mounts :
628+ existing_mount = list (op_spec .mount ) if op_spec .mount else []
629+ op_spec .mount = existing_mount + cli_mounts
630+
593631 _run (
594632 ctx = ctx ,
595633 name = name ,
0 commit comments