Skip to content

Commit 0b3af05

Browse files
committed
Merge branch 'feature/build-script-improvements' into 'develop'
Feature/build script improvements See merge request genaiic-reusable-assets/engagement-artifacts/genaiic-idp-accelerator!264
2 parents a5836e0 + 62f125e commit 0b3af05

File tree

4 files changed

+547
-602
lines changed

4 files changed

+547
-602
lines changed

lib/idp_common_pkg/tests/unit/test_publish.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ def test_run_minimal_success_flow(self):
10441044
patch.object(publisher, "check_parameters") as mock_check_params,
10451045
patch.object(publisher, "setup_environment") as mock_setup_env,
10461046
patch.object(publisher, "check_prerequisites") as mock_check_prereq,
1047+
patch.object(publisher, "ensure_aws_sam_directory") as mock_ensure_sam,
10471048
patch.object(publisher, "setup_artifacts_bucket") as mock_setup_bucket,
10481049
patch.object(publisher, "clean_temp_files"),
10491050
patch.object(publisher, "clean_lib"),
@@ -1072,6 +1073,7 @@ def test_run_minimal_success_flow(self):
10721073
mock_check_params.assert_called_once()
10731074
mock_setup_env.assert_called_once()
10741075
mock_check_prereq.assert_called_once()
1076+
mock_ensure_sam.assert_called_once()
10751077
mock_setup_bucket.assert_called_once()
10761078
mock_build_patterns.assert_called_once()
10771079
mock_build_options.assert_called_once()
@@ -1121,6 +1123,7 @@ def test_run_pattern_build_failure(self):
11211123
patch.object(publisher, "check_parameters"),
11221124
patch.object(publisher, "setup_environment"),
11231125
patch.object(publisher, "check_prerequisites"),
1126+
patch.object(publisher, "ensure_aws_sam_directory"),
11241127
patch.object(publisher, "setup_artifacts_bucket"),
11251128
patch.object(publisher, "clean_temp_files"),
11261129
patch.object(publisher, "clean_lib"),

publish.py

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
TextColumn,
3636
TimeElapsedColumn,
3737
)
38-
from rich.table import Table
3938

4039

4140
class IDPPublisher:
@@ -107,7 +106,7 @@ def print_usage(self):
107106
"""Print usage information with Rich formatting"""
108107
self.console.print("\n[bold cyan]Usage:[/bold cyan]")
109108
self.console.print(
110-
" python3 publish.py <cfn_bucket_basename> <cfn_prefix> <region> [public] [--max-workers N]"
109+
" python3 publish.py <cfn_bucket_basename> <cfn_prefix> <region> [public] [--max-workers N] [--verbose]"
111110
)
112111

113112
self.console.print("\n[bold cyan]Parameters:[/bold cyan]")
@@ -125,6 +124,9 @@ def print_usage(self):
125124
self.console.print(
126125
" Use 1 for sequential processing, higher numbers for more concurrency"
127126
)
127+
self.console.print(
128+
" [yellow][--verbose, -v][/yellow]: Optional. Enable verbose output for debugging"
129+
)
128130

129131
def check_parameters(self, args):
130132
"""Check and validate input parameters"""
@@ -179,6 +181,9 @@ def check_parameters(self, args):
179181
)
180182
self.print_usage()
181183
sys.exit(1)
184+
elif arg in ["--verbose", "-v"]:
185+
# Verbose flag is already handled by Typer, just acknowledge it here
186+
pass
182187
else:
183188
self.console.print(
184189
f"[yellow]Warning: Unknown argument '{arg}' ignored[/yellow]"
@@ -263,6 +268,22 @@ def check_prerequisites(self):
263268
)
264269
sys.exit(1)
265270

271+
def ensure_aws_sam_directory(self):
272+
"""Ensure .aws-sam directory exists"""
273+
aws_sam_dir = ".aws-sam"
274+
275+
if not os.path.exists(aws_sam_dir):
276+
self.console.print(
277+
"[yellow].aws-sam directory not found. Creating it...[/yellow]"
278+
)
279+
os.makedirs(aws_sam_dir, exist_ok=True)
280+
self.console.print(
281+
"[green]✅ Successfully created .aws-sam directory[/green]"
282+
)
283+
else:
284+
if self.verbose:
285+
self.console.print("[dim].aws-sam directory already exists[/dim]")
286+
266287
def version_compare(self, version1, version2):
267288
"""Compare two version strings. Returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2"""
268289

@@ -365,6 +386,7 @@ def get_directory_checksum(self, directory):
365386
".git",
366387
".vscode",
367388
".idea",
389+
"test-reports", # Exclude test report directories
368390
}
369391

370392
exclude_file_patterns = {
@@ -379,9 +401,19 @@ def get_directory_checksum(self, directory):
379401
".coverage",
380402
".DS_Store",
381403
"Thumbs.db",
404+
"coverage.xml", # Coverage reports
405+
"test-results.xml", # Test result reports
406+
".gitkeep", # Git placeholder files
382407
}
383408

384-
exclude_file_suffixes = (".pyc", ".pyo", ".pyd", ".so", ".coverage")
409+
exclude_file_suffixes = (
410+
".pyc",
411+
".pyo",
412+
".pyd",
413+
".so",
414+
".coverage",
415+
".log", # Log files
416+
)
385417
exclude_dir_suffixes = (".egg-info",)
386418

387419
def should_exclude_dir(dir_name):
@@ -405,7 +437,12 @@ def should_exclude_file(file_name):
405437
return True
406438
# Exclude test files for library checksum only
407439
if "lib" in directory and (
408-
file_name.startswith("test_") or file_name.endswith("_test.py")
440+
file_name.startswith("test_")
441+
or file_name.endswith("_test.py")
442+
or file_name == "nodeids" # pytest cache files
443+
or file_name == "lastfailed" # pytest cache files
444+
or file_name
445+
in ["coverage.xml", "test-results.xml"] # specific test report files
409446
):
410447
return True
411448
return False
@@ -458,6 +495,17 @@ def get_stored_checksum(self, directory):
458495

459496
def needs_rebuild(self, *paths):
460497
"""Check if any of the paths have changed since last build"""
498+
# Special case for ./lib directory - use .lib_checksum in root and get_directory_checksum
499+
if len(paths) == 1 and paths[0] == "./lib":
500+
current_checksum = self.get_directory_checksum("./lib")
501+
checksum_file = ".lib_checksum"
502+
if os.path.exists(checksum_file):
503+
with open(checksum_file, "r") as f:
504+
stored_checksum = f.read().strip()
505+
return current_checksum != stored_checksum
506+
return True
507+
508+
# For all other cases, use get_checksum
461509
current_checksum = self.get_checksum(*paths)
462510

463511
# For single directory, check its stored checksum
@@ -1164,30 +1212,7 @@ def print_outputs(self):
11641212
encoded_template_url = quote(template_url, safe=":/?#[]@!$&'()*+,;=")
11651213
launch_url = f"https://{self.region}.console.aws.amazon.com/cloudformation/home?region={self.region}#/stacks/create/review?templateURL={encoded_template_url}&stackName=IDP"
11661214

1167-
# First, display URLs in plain text to avoid Rich formatting issues
1168-
self.console.print("\n[bold green]Deployment Outputs[/bold green]")
1169-
self.console.print("[cyan]Template URL (use to update existing stack):[/cyan]")
1170-
self.console.print(f"{template_url}")
1171-
self.console.print(
1172-
"\n[cyan]1-Click Launch URL (use to launch new stack):[/cyan]"
1173-
)
1174-
self.console.print(f"{launch_url}")
1175-
1176-
# Also display in a table with clickable links
1177-
table = Table(title="[bold green]Quick Links[/bold green]", show_lines=True)
1178-
table.add_column("Link", style="cyan", no_wrap=False, width=60)
1179-
table.add_column("Description", style="yellow", width=40)
1180-
1181-
# Create clickable links using Rich's link syntax
1182-
template_link = f"[link={template_url}]Template URL[/link]"
1183-
launch_link = f"[link={launch_url}]1-Click Launch[/link]"
1184-
1185-
table.add_row(template_link, "Go to cloudformation and update existing stack")
1186-
table.add_row(launch_link, "Use to launch new stack")
1187-
1188-
self.console.print(table)
1189-
1190-
# Additional information for troubleshooting
1215+
# Display deployment information first
11911216
self.console.print("\n[bold cyan]Deployment Information:[/bold cyan]")
11921217
self.console.print(f" • Region: [yellow]{self.region}[/yellow]")
11931218
self.console.print(f" • Bucket: [yellow]{self.bucket}[/yellow]")
@@ -1198,6 +1223,15 @@ def print_outputs(self):
11981223
f" • Public Access: [yellow]{'Yes' if self.public else 'No'}[/yellow]"
11991224
)
12001225

1226+
# Then display URLs
1227+
self.console.print("\n[bold green]Deployment Outputs[/bold green]")
1228+
self.console.print("[cyan]Template URL (use to update existing stack):[/cyan]")
1229+
self.console.print(f"{template_url}")
1230+
self.console.print(
1231+
"\n[cyan]1-Click Launch URL (use to launch new stack):[/cyan]"
1232+
)
1233+
self.console.print(f"{launch_url}")
1234+
12011235
def run(self, args):
12021236
"""Main execution method"""
12031237
try:
@@ -1210,6 +1244,9 @@ def run(self, args):
12101244
# Check prerequisites
12111245
self.check_prerequisites()
12121246

1247+
# Ensure .aws-sam directory exists
1248+
self.ensure_aws_sam_directory()
1249+
12131250
# Set up S3 bucket
12141251
self.setup_artifacts_bucket()
12151252

0 commit comments

Comments
 (0)