@@ -103,23 +103,26 @@ def execute_action(
103103 validate_first : bool = False ,
104104 substitute : bool = False ,
105105 ) -> dict [str , Any ]:
106- """Execute every action; return ``{"execute: <action>": result|repr(error)}``.
106+ """Execute every action; return ``{"execute[<index>] : <action>": result|repr(error)}``.
107107
108108 ``dry_run=True`` logs and records the resolved name without invoking the
109109 command. ``validate_first=True`` runs :meth:`validate` before touching
110110 any action so a typo aborts the whole batch up-front. ``substitute=True``
111111 expands ``${env:...}`` / ``${date:...}`` / ``${uuid}`` / ``${cwd}``
112- placeholders inside every string in the payload.
112+ placeholders inside every string in the payload — the original
113+ (un-substituted) action is used for log lines and result keys so
114+ secrets pulled in via ``${env:...}`` never reach logs.
113115 """
114116 actions = self ._coerce (action_list )
115- if substitute :
116- actions = substitute_payload (actions ) # type: ignore[assignment]
117+ executed : list = (
118+ substitute_payload (actions ) if substitute else actions # type: ignore[assignment]
119+ )
117120 if validate_first :
118- self .validate (actions )
121+ self .validate (executed )
119122 results : dict [str , Any ] = {}
120- for action in actions :
121- key = f"execute: { action } "
122- results [key ] = self ._run_one (action , dry_run = dry_run )
123+ for index , ( display , action ) in enumerate ( zip ( actions , executed , strict = True )) :
124+ key = f"execute[ { index } ] : { display } "
125+ results [key ] = self ._run_one (action , dry_run = dry_run , display = display )
123126 return results
124127
125128 def execute_action_parallel (
@@ -154,15 +157,16 @@ def add_command_to_executor(self, command_dict: Mapping[str, Any]) -> None:
154157 self .registry .register_many (command_dict )
155158
156159 # Internals ---------------------------------------------------------
157- def _run_one (self , action : list , dry_run : bool ) -> Any :
160+ def _run_one (self , action : list , dry_run : bool , display : list | None = None ) -> Any :
161+ display_action = action if display is None else display
158162 name = _safe_action_name (action )
159163 if dry_run :
160- return self ._run_dry (action )
164+ return self ._run_dry (action , display = display_action )
161165 started = time .monotonic ()
162166 ok = False
163167 try :
164168 value = self ._execute_event (action )
165- file_automation_logger .info ("execute_action: %s" , action )
169+ file_automation_logger .info ("execute_action: %s" , display_action )
166170 ok = True
167171 return value
168172 except ExecuteActionException as error :
@@ -174,19 +178,21 @@ def _run_one(self, action: list, dry_run: bool) -> Any:
174178 finally :
175179 record_action (name , time .monotonic () - started , ok )
176180
177- def _run_dry (self , action : list ) -> Any :
181+ def _run_dry (self , action : list , display : list | None = None ) -> Any :
182+ display_action = action if display is None else display
178183 try :
179- name , kind , payload = self ._parse_action (action )
184+ name , _ , _ = self ._parse_action (action )
180185 if self .registry .resolve (name ) is None :
181186 raise ExecuteActionException (f"unknown action: { name !r} " )
182187 except ExecuteActionException as error :
183188 file_automation_logger .error ("execute_action malformed: %r" , error )
184189 return repr (error )
190+ _ , display_kind , display_payload = self ._parse_action (display_action )
185191 file_automation_logger .info (
186192 "dry_run: %s kind=%s payload=%r" ,
187193 name ,
188- kind ,
189- payload ,
194+ display_kind ,
195+ display_payload ,
190196 )
191197 return f"dry_run:{ name } "
192198
0 commit comments