diff --git a/CHANGELOG.md b/CHANGELOG.md index 58f0745..45251a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # Changelog -## 1.9.1 (2025-10-15) +## 1.9.2 (2025-10-16) - added `--output-file` argument +- added stack level `exports` - pre defined `stack_name`, `stack_env`, `elapsed_time` and user defined - Added performance enhancement query strategy - Added tab completion - Added enhanced logging decorators diff --git a/examples/databricks/serverless/outputs/deployment.json b/examples/databricks/serverless/outputs/deployment.json index 70b16e7..2e6250c 100644 --- a/examples/databricks/serverless/outputs/deployment.json +++ b/examples/databricks/serverless/outputs/deployment.json @@ -5,5 +5,6 @@ "databricks_workspace_id": "4014389171618363", "databricks_deployment_name": "dbc-5a3a87f7-6914", "databricks_workspace_status": "RUNNING", - "databricks_workspace_url": "https://dbc-5a3a87f7-6914.cloud.databricks.com" + "databricks_workspace_url": "https://dbc-5a3a87f7-6914.cloud.databricks.com", + "elapsed_time": "0:00:31.470746" } \ No newline at end of file diff --git a/examples/databricks/serverless/outputs/test.json b/examples/databricks/serverless/outputs/test.json new file mode 100644 index 0000000..0bb1932 --- /dev/null +++ b/examples/databricks/serverless/outputs/test.json @@ -0,0 +1,10 @@ +{ + "stack_name": "stackql-serverless", + "stack_env": "prd", + "databricks_workspace_name": "stackql-serverless-prd-workspace", + "databricks_workspace_id": "4014389171618363", + "databricks_deployment_name": "dbc-5a3a87f7-6914", + "databricks_workspace_status": "RUNNING", + "databricks_workspace_url": "https://dbc-5a3a87f7-6914.cloud.databricks.com", + "elapsed_time": "0:00:18.247444" +} \ No newline at end of file diff --git a/setup.py b/setup.py index bd6ff6f..e5cea3c 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup( name='stackql-deploy', - version='1.9.1', + version='1.9.2', description='Model driven resource provisioning and deployment framework using StackQL.', long_description=readme, long_description_content_type='text/x-rst', diff --git a/stackql_deploy/__init__.py b/stackql_deploy/__init__.py index 487d853..8e2b7ed 100644 --- a/stackql_deploy/__init__.py +++ b/stackql_deploy/__init__.py @@ -1 +1 @@ -__version__ = '1.9.1' +__version__ = '1.9.2' diff --git a/stackql_deploy/cmd/base.py b/stackql_deploy/cmd/base.py index 65c2e75..d63593d 100644 --- a/stackql_deploy/cmd/base.py +++ b/stackql_deploy/cmd/base.py @@ -471,7 +471,7 @@ def run_command(self, command_query, command_retries, command_retry_delay, dry_r else: self.logger.info("command query not configured, skipping command...") - def process_stack_exports(self, dry_run, output_file=None): + def process_stack_exports(self, dry_run, output_file=None, elapsed_time=None): """ Process root-level exports from manifest and write to JSON file """ @@ -483,18 +483,18 @@ def process_stack_exports(self, dry_run, output_file=None): manifest_exports = self.manifest.get('exports', []) if dry_run: - total_vars = len(manifest_exports) + 2 # +2 for stack_name and stack_env + total_vars = len(manifest_exports) + 3 # +3 for stack_name, stack_env, and elapsed_time self.logger.info( f"📁 dry run: would export {total_vars} variables to {output_file} " - f"(including automatic stack_name and stack_env)" + f"(including automatic stack_name, stack_env, and elapsed_time)" ) return - # Collect data from global context + # Collect data in specific order: stack metadata first, user exports, then timing export_data = {} missing_vars = [] - # Always include stack_name and stack_env automatically + # Always include stack_name and stack_env automatically as first exports export_data['stack_name'] = self.stack_name export_data['stack_env'] = self.stack_env @@ -522,6 +522,10 @@ def process_stack_exports(self, dry_run, output_file=None): self.logger ) + # Add elapsed_time as the final automatic export + if elapsed_time is not None: + export_data['elapsed_time'] = str(elapsed_time) + # Ensure destination directory exists dest_dir = os.path.dirname(output_file) if dest_dir and not os.path.exists(dest_dir): diff --git a/stackql_deploy/cmd/build.py b/stackql_deploy/cmd/build.py index dbd1b0c..6805059 100644 --- a/stackql_deploy/cmd/build.py +++ b/stackql_deploy/cmd/build.py @@ -409,8 +409,8 @@ def run(self, dry_run, show_queries, on_failure, output_file=None): elif type == 'query': self.logger.info(f"✅ successfully exported variables for query in {resource['name']}") - # Process stack-level exports after all resources are deployed - self.process_stack_exports(dry_run, output_file) - elapsed_time = datetime.datetime.now() - start_time self.logger.info(f"deployment completed in {elapsed_time}") + + # Process stack-level exports after all resources are deployed + self.process_stack_exports(dry_run, output_file, elapsed_time) diff --git a/stackql_deploy/cmd/test.py b/stackql_deploy/cmd/test.py index 7f61e93..2cb2100 100644 --- a/stackql_deploy/cmd/test.py +++ b/stackql_deploy/cmd/test.py @@ -149,4 +149,4 @@ def run(self, dry_run, show_queries, on_failure, output_file=None): # Process stack-level exports if specified if output_file: - self.process_stack_exports(dry_run, output_file) + self.process_stack_exports(dry_run, output_file, elapsed_time) diff --git a/website/docs/manifest_fields/exports.mdx b/website/docs/manifest_fields/exports.mdx index 75c523c..04d945b 100644 --- a/website/docs/manifest_fields/exports.mdx +++ b/website/docs/manifest_fields/exports.mdx @@ -15,7 +15,9 @@ exports: ``` **Notes**: -- `stack_name` and `stack_env` are automatically included in exports and do not need to be listed +- `stack_name`, `stack_env`, and `elapsed_time` are automatically included in exports and do not need to be listed +- Export order: automatic exports (`stack_name`, `stack_env`) first, then user-defined exports, then timing (`elapsed_time`) last +- `elapsed_time` is formatted as a string showing the total deployment duration (e.g., "0:01:23.456789") - Variables are exported exactly as they exist in the deployment context - Complex objects and arrays are preserved as JSON structures - If a listed variable doesn't exist in the context, deployment will fail