superset-showtime 0.5.18__py3-none-any.whl → 0.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of superset-showtime might be problematic. Click here for more details.
- showtime/__init__.py +1 -1
- showtime/cli.py +106 -128
- showtime/core/github.py +67 -4
- showtime/core/pull_request.py +31 -16
- {superset_showtime-0.5.18.dist-info → superset_showtime-0.6.4.dist-info}/METADATA +1 -1
- {superset_showtime-0.5.18.dist-info → superset_showtime-0.6.4.dist-info}/RECORD +8 -8
- {superset_showtime-0.5.18.dist-info → superset_showtime-0.6.4.dist-info}/WHEEL +0 -0
- {superset_showtime-0.5.18.dist-info → superset_showtime-0.6.4.dist-info}/entry_points.txt +0 -0
showtime/__init__.py
CHANGED
showtime/cli.py
CHANGED
|
@@ -584,36 +584,6 @@ def sync(
|
|
|
584
584
|
raise typer.Exit(1) from e
|
|
585
585
|
|
|
586
586
|
|
|
587
|
-
@app.command()
|
|
588
|
-
def handle_sync(pr_number: int) -> None:
|
|
589
|
-
"""🎪 Handle new commit sync (called by GitHub Actions on PR synchronize)"""
|
|
590
|
-
try:
|
|
591
|
-
pr = PullRequest.from_id(pr_number)
|
|
592
|
-
|
|
593
|
-
# Only sync if there's an active environment
|
|
594
|
-
if not pr.current_show:
|
|
595
|
-
p(f"🎪 No active environment for PR #{pr_number} - skipping sync")
|
|
596
|
-
return
|
|
597
|
-
|
|
598
|
-
# Get latest commit SHA
|
|
599
|
-
from .core.pull_request import get_github
|
|
600
|
-
|
|
601
|
-
latest_sha = get_github().get_latest_commit_sha(pr_number)
|
|
602
|
-
|
|
603
|
-
# Check if update is needed
|
|
604
|
-
if not pr.current_show.needs_update(latest_sha):
|
|
605
|
-
p(f"🎪 Environment already up to date for PR #{pr_number}")
|
|
606
|
-
return
|
|
607
|
-
|
|
608
|
-
p(f"🎪 Syncing PR #{pr_number} to commit {latest_sha[:7]}")
|
|
609
|
-
|
|
610
|
-
# TODO: Implement rolling update logic
|
|
611
|
-
p("🎪 [bold yellow]Sync logic not yet implemented[/bold yellow]")
|
|
612
|
-
|
|
613
|
-
except Exception as e:
|
|
614
|
-
p(f"🎪 [bold red]Error handling sync:[/bold red] {e}")
|
|
615
|
-
|
|
616
|
-
|
|
617
587
|
@app.command()
|
|
618
588
|
def setup_labels(
|
|
619
589
|
dry_run: bool = typer.Option(False, "--dry-run", help="Show what labels would be created"),
|
|
@@ -662,107 +632,10 @@ def setup_labels(
|
|
|
662
632
|
p(f"🎪 [bold red]Error setting up labels:[/bold red] {e}")
|
|
663
633
|
|
|
664
634
|
|
|
665
|
-
@app.command()
|
|
666
|
-
def aws_cleanup(
|
|
667
|
-
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would be cleaned"),
|
|
668
|
-
force: bool = typer.Option(False, "--force", help="Delete all showtime AWS resources"),
|
|
669
|
-
) -> None:
|
|
670
|
-
"""🧹 Clean up orphaned AWS resources without GitHub labels"""
|
|
671
|
-
try:
|
|
672
|
-
from .core.aws import AWSInterface
|
|
673
|
-
|
|
674
|
-
aws = AWSInterface()
|
|
675
|
-
|
|
676
|
-
p("🔍 [bold blue]Scanning for orphaned AWS resources...[/bold blue]")
|
|
677
|
-
|
|
678
|
-
# 1. Get all GitHub PRs with circus labels
|
|
679
|
-
github_services = set()
|
|
680
|
-
try:
|
|
681
|
-
all_pr_numbers = PullRequest.find_all_with_environments()
|
|
682
|
-
p(f"📋 Found {len(all_pr_numbers)} PRs with circus labels:")
|
|
683
|
-
|
|
684
|
-
for pr_number in all_pr_numbers:
|
|
685
|
-
pr = PullRequest.from_id(pr_number)
|
|
686
|
-
p(
|
|
687
|
-
f" 🎪 PR #{pr_number}: {len(pr.shows)} shows, {len(pr.circus_labels)} circus labels"
|
|
688
|
-
)
|
|
689
|
-
|
|
690
|
-
for show in pr.shows:
|
|
691
|
-
service_name = show.ecs_service_name
|
|
692
|
-
github_services.add(service_name)
|
|
693
|
-
p(f" 📝 Expected service: {service_name}")
|
|
694
|
-
|
|
695
|
-
# Show labels for debugging
|
|
696
|
-
if not pr.shows:
|
|
697
|
-
p(f" ⚠️ No shows found, labels: {pr.circus_labels[:3]}...") # First 3 labels
|
|
698
|
-
|
|
699
|
-
except Exception as e:
|
|
700
|
-
p(f"⚠️ GitHub scan failed: {e}")
|
|
701
|
-
github_services = set()
|
|
702
|
-
|
|
703
|
-
# 2. Get all AWS ECS services matching showtime pattern
|
|
704
|
-
p("\n☁️ [bold blue]Scanning AWS ECS services...[/bold blue]")
|
|
705
|
-
try:
|
|
706
|
-
aws_services = aws.find_showtime_services()
|
|
707
|
-
p(f"🔍 Found {len(aws_services)} AWS services with pr-* pattern")
|
|
708
|
-
|
|
709
|
-
for service in aws_services:
|
|
710
|
-
p(f" ☁️ AWS: {service}")
|
|
711
|
-
except Exception as e:
|
|
712
|
-
p(f"❌ AWS scan failed: {e}")
|
|
713
|
-
return
|
|
714
|
-
|
|
715
|
-
# 3. Find orphaned services
|
|
716
|
-
orphaned = [service for service in aws_services if service not in github_services]
|
|
717
|
-
|
|
718
|
-
if not orphaned:
|
|
719
|
-
p("\n✅ [bold green]No orphaned AWS resources found![/bold green]")
|
|
720
|
-
return
|
|
721
|
-
|
|
722
|
-
p(f"\n🚨 [bold red]Found {len(orphaned)} orphaned AWS resources:[/bold red]")
|
|
723
|
-
for service in orphaned:
|
|
724
|
-
p(f" 💰 {service} (consuming resources)")
|
|
725
|
-
|
|
726
|
-
if dry_run:
|
|
727
|
-
p(f"\n🎪 [bold yellow]DRY RUN[/bold yellow] - Would delete {len(orphaned)} services")
|
|
728
|
-
return
|
|
729
|
-
|
|
730
|
-
if not force:
|
|
731
|
-
confirm = typer.confirm(f"Delete {len(orphaned)} orphaned AWS services?")
|
|
732
|
-
if not confirm:
|
|
733
|
-
p("🎪 Cancelled")
|
|
734
|
-
return
|
|
735
|
-
|
|
736
|
-
# 4. Delete orphaned resources
|
|
737
|
-
deleted_count = 0
|
|
738
|
-
for service in orphaned:
|
|
739
|
-
p(f"🗑️ Deleting {service}...")
|
|
740
|
-
try:
|
|
741
|
-
# Extract PR number for delete_environment call
|
|
742
|
-
pr_match = service.replace("pr-", "").replace("-service", "")
|
|
743
|
-
parts = pr_match.split("-")
|
|
744
|
-
if len(parts) >= 2:
|
|
745
|
-
pr_number = int(parts[0])
|
|
746
|
-
success = aws.delete_environment(service, pr_number)
|
|
747
|
-
if success:
|
|
748
|
-
p(f"✅ Deleted {service}")
|
|
749
|
-
deleted_count += 1
|
|
750
|
-
else:
|
|
751
|
-
p(f"❌ Failed to delete {service}")
|
|
752
|
-
else:
|
|
753
|
-
p(f"❌ Invalid service name format: {service}")
|
|
754
|
-
except Exception as e:
|
|
755
|
-
p(f"❌ Error deleting {service}: {e}")
|
|
756
|
-
|
|
757
|
-
p(f"\n🎪 ✅ Cleanup complete: deleted {deleted_count}/{len(orphaned)} services")
|
|
758
|
-
|
|
759
|
-
except Exception as e:
|
|
760
|
-
p(f"❌ AWS cleanup failed: {e}")
|
|
761
|
-
|
|
762
|
-
|
|
763
635
|
@app.command()
|
|
764
636
|
def cleanup(
|
|
765
637
|
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would be cleaned"),
|
|
638
|
+
force: bool = typer.Option(False, "--force", help="Skip interactive prompts"),
|
|
766
639
|
older_than: str = typer.Option(
|
|
767
640
|
"48h", "--older-than", help="Clean environments older than this (ignored if --respect-ttl)"
|
|
768
641
|
),
|
|
@@ -777,6 +650,11 @@ def cleanup(
|
|
|
777
650
|
"--cleanup-labels/--no-cleanup-labels",
|
|
778
651
|
help="Also cleanup SHA-based label definitions from repository",
|
|
779
652
|
),
|
|
653
|
+
cleanup_aws_orphans: bool = typer.Option(
|
|
654
|
+
True,
|
|
655
|
+
"--cleanup-aws-orphans/--no-cleanup-aws-orphans",
|
|
656
|
+
help="Also cleanup orphaned AWS resources",
|
|
657
|
+
),
|
|
780
658
|
) -> None:
|
|
781
659
|
"""🎪 Clean up orphaned or expired environments and labels"""
|
|
782
660
|
try:
|
|
@@ -811,6 +689,106 @@ def cleanup(
|
|
|
811
689
|
else:
|
|
812
690
|
p("🎪 No expired environments found")
|
|
813
691
|
|
|
692
|
+
# Phase 2: AWS orphan cleanup
|
|
693
|
+
aws_cleaned_count = 0
|
|
694
|
+
if cleanup_aws_orphans:
|
|
695
|
+
from .core.aws import AWSInterface
|
|
696
|
+
|
|
697
|
+
p("\n☁️ [bold blue]Scanning for orphaned AWS resources...[/bold blue]")
|
|
698
|
+
aws = AWSInterface()
|
|
699
|
+
|
|
700
|
+
try:
|
|
701
|
+
# Get expected services from GitHub
|
|
702
|
+
github_services = set()
|
|
703
|
+
for pr_number in pr_numbers:
|
|
704
|
+
pr = PullRequest.from_id(pr_number)
|
|
705
|
+
for show in pr.shows:
|
|
706
|
+
github_services.add(show.ecs_service_name)
|
|
707
|
+
|
|
708
|
+
# Find AWS orphans
|
|
709
|
+
aws_services = aws.list_circus_environments()
|
|
710
|
+
aws_orphans = [
|
|
711
|
+
svc for svc in aws_services if svc.get("service_name") not in github_services
|
|
712
|
+
]
|
|
713
|
+
|
|
714
|
+
if aws_orphans:
|
|
715
|
+
p(f"☁️ Found {len(aws_orphans)} orphaned AWS resources:")
|
|
716
|
+
for orphan in aws_orphans[:3]:
|
|
717
|
+
p(f" • {orphan['service_name']}")
|
|
718
|
+
if len(aws_orphans) > 3:
|
|
719
|
+
p(f" ... and {len(aws_orphans) - 3} more")
|
|
720
|
+
|
|
721
|
+
if not force and not dry_run:
|
|
722
|
+
if typer.confirm(f"Delete {len(aws_orphans)} orphaned AWS resources?"):
|
|
723
|
+
# Clean up AWS orphans
|
|
724
|
+
for orphan in aws_orphans:
|
|
725
|
+
if not dry_run:
|
|
726
|
+
aws.delete_service(orphan["service_name"])
|
|
727
|
+
aws_cleaned_count += 1
|
|
728
|
+
else:
|
|
729
|
+
p("❌ Skipping AWS orphan cleanup")
|
|
730
|
+
elif force or dry_run:
|
|
731
|
+
aws_cleaned_count = len(aws_orphans)
|
|
732
|
+
if not dry_run:
|
|
733
|
+
for orphan in aws_orphans:
|
|
734
|
+
aws.delete_service(orphan["service_name"])
|
|
735
|
+
|
|
736
|
+
if aws_cleaned_count > 0:
|
|
737
|
+
p(f"☁️ ✅ Cleaned up {aws_cleaned_count} orphaned AWS resources")
|
|
738
|
+
else:
|
|
739
|
+
p("☁️ No orphaned AWS resources found")
|
|
740
|
+
|
|
741
|
+
except Exception as e:
|
|
742
|
+
p(f"⚠️ AWS orphan scan failed: {e}")
|
|
743
|
+
|
|
744
|
+
# Phase 3: Repository label cleanup
|
|
745
|
+
label_cleaned_count = 0
|
|
746
|
+
if cleanup_labels:
|
|
747
|
+
from .core.pull_request import get_github
|
|
748
|
+
|
|
749
|
+
p("\n🏷️ [bold blue]Scanning for orphaned repository labels...[/bold blue]")
|
|
750
|
+
github = get_github()
|
|
751
|
+
|
|
752
|
+
try:
|
|
753
|
+
orphaned_labels = github.find_orphaned_labels(dry_run=True) # Preview
|
|
754
|
+
|
|
755
|
+
if orphaned_labels:
|
|
756
|
+
p(f"🏷️ Found {len(orphaned_labels)} orphaned repository labels:")
|
|
757
|
+
for label in orphaned_labels[:3]:
|
|
758
|
+
p(f" • {label}")
|
|
759
|
+
if len(orphaned_labels) > 3:
|
|
760
|
+
p(f" ... and {len(orphaned_labels) - 3} more")
|
|
761
|
+
|
|
762
|
+
if not force and not dry_run:
|
|
763
|
+
if typer.confirm(
|
|
764
|
+
f"Delete {len(orphaned_labels)} orphaned labels from repository?"
|
|
765
|
+
):
|
|
766
|
+
deleted_labels = github.find_orphaned_labels(dry_run=False)
|
|
767
|
+
label_cleaned_count = len(deleted_labels)
|
|
768
|
+
else:
|
|
769
|
+
p("❌ Skipping repository label cleanup")
|
|
770
|
+
elif force or dry_run:
|
|
771
|
+
label_cleaned_count = len(orphaned_labels)
|
|
772
|
+
if not dry_run:
|
|
773
|
+
github.find_orphaned_labels(dry_run=False)
|
|
774
|
+
|
|
775
|
+
if label_cleaned_count > 0:
|
|
776
|
+
p(f"🏷️ ✅ Cleaned up {label_cleaned_count} orphaned repository labels")
|
|
777
|
+
else:
|
|
778
|
+
p("🏷️ No orphaned repository labels found")
|
|
779
|
+
|
|
780
|
+
except Exception as e:
|
|
781
|
+
p(f"⚠️ Repository label scan failed: {e}")
|
|
782
|
+
|
|
783
|
+
# Final summary
|
|
784
|
+
total_cleaned = cleaned_count + aws_cleaned_count + label_cleaned_count
|
|
785
|
+
if total_cleaned > 0:
|
|
786
|
+
p(
|
|
787
|
+
f"\n🎉 [bold green]Total cleanup: {cleaned_count} environments + {aws_cleaned_count} AWS orphans + {label_cleaned_count} labels[/bold green]"
|
|
788
|
+
)
|
|
789
|
+
else:
|
|
790
|
+
p("\n✨ [bold green]No cleanup needed - everything is clean![/bold green]")
|
|
791
|
+
|
|
814
792
|
except Exception as e:
|
|
815
793
|
p(f"❌ Cleanup failed: {e}")
|
|
816
794
|
|
showtime/core/github.py
CHANGED
|
@@ -143,9 +143,9 @@ class GitHubInterface:
|
|
|
143
143
|
url = f"{self.base_url}/search/issues"
|
|
144
144
|
# Search for PRs with any circus tent labels
|
|
145
145
|
params = {
|
|
146
|
-
"q": f"repo:{self.org}/{self.repo} is:pr 🎪",
|
|
146
|
+
"q": f"repo:{self.org}/{self.repo} is:pr is:open 🎪",
|
|
147
147
|
"per_page": "100",
|
|
148
|
-
} #
|
|
148
|
+
} # Only open PRs - closed PRs should have cleaned up labels
|
|
149
149
|
|
|
150
150
|
with httpx.Client() as client:
|
|
151
151
|
response = client.get(url, headers=self.headers, params=params)
|
|
@@ -209,8 +209,8 @@ class GitHubInterface:
|
|
|
209
209
|
all_labels = self.get_repository_labels()
|
|
210
210
|
sha_labels = []
|
|
211
211
|
|
|
212
|
-
# Find labels with SHA patterns (7+ hex chars
|
|
213
|
-
sha_pattern = re.compile(r"^🎪 .*
|
|
212
|
+
# Find labels with SHA patterns (7+ hex chars anywhere in label)
|
|
213
|
+
sha_pattern = re.compile(r"^🎪 .*[a-f0-9]{7,}.*$")
|
|
214
214
|
|
|
215
215
|
for label in all_labels:
|
|
216
216
|
if sha_pattern.match(label):
|
|
@@ -225,6 +225,69 @@ class GitHubInterface:
|
|
|
225
225
|
|
|
226
226
|
return sha_labels
|
|
227
227
|
|
|
228
|
+
def find_orphaned_labels(self, dry_run: bool = False) -> List[str]:
|
|
229
|
+
"""Find labels that exist in repository but aren't used on any PR"""
|
|
230
|
+
import re
|
|
231
|
+
|
|
232
|
+
print("🔍 Scanning repository labels...")
|
|
233
|
+
|
|
234
|
+
# 1. Get all repository labels with SHA patterns
|
|
235
|
+
all_repo_labels = self.get_repository_labels()
|
|
236
|
+
sha_pattern = re.compile(r"^🎪 .*[a-f0-9]{7,}.*$")
|
|
237
|
+
sha_repo_labels = {label for label in all_repo_labels if sha_pattern.match(label)}
|
|
238
|
+
|
|
239
|
+
print(f"📋 Found {len(sha_repo_labels)} SHA-containing labels in repository")
|
|
240
|
+
|
|
241
|
+
# 2. Get all labels actually used on PRs with circus labels
|
|
242
|
+
print("🔍 Scanning PRs with circus labels...")
|
|
243
|
+
|
|
244
|
+
# Import here to avoid circular import
|
|
245
|
+
import importlib
|
|
246
|
+
|
|
247
|
+
pull_request_module = importlib.import_module("showtime.core.pull_request")
|
|
248
|
+
PullRequest = pull_request_module.PullRequest
|
|
249
|
+
|
|
250
|
+
try:
|
|
251
|
+
pr_numbers = PullRequest.find_all_with_environments()
|
|
252
|
+
print(f"📋 Found {len(pr_numbers)} PRs with circus labels")
|
|
253
|
+
|
|
254
|
+
used_labels = set()
|
|
255
|
+
for pr_number in pr_numbers:
|
|
256
|
+
pr_labels = self.get_labels(pr_number)
|
|
257
|
+
circus_labels = {label for label in pr_labels if label.startswith("🎪 ")}
|
|
258
|
+
used_labels.update(circus_labels)
|
|
259
|
+
|
|
260
|
+
print(f"📋 Found {len(used_labels)} circus labels actually used on PRs")
|
|
261
|
+
|
|
262
|
+
# 3. Set difference to find orphaned labels
|
|
263
|
+
orphaned_labels = sha_repo_labels - used_labels
|
|
264
|
+
|
|
265
|
+
print(f"🗑️ Found {len(orphaned_labels)} truly orphaned labels")
|
|
266
|
+
|
|
267
|
+
# Debug: Show some examples if in dry run
|
|
268
|
+
if dry_run and orphaned_labels:
|
|
269
|
+
print("🔍 Examples of orphaned labels:")
|
|
270
|
+
for label in list(orphaned_labels)[:5]:
|
|
271
|
+
print(f" • {label}")
|
|
272
|
+
if dry_run and used_labels:
|
|
273
|
+
print("🔍 Examples of used labels:")
|
|
274
|
+
for label in list(used_labels)[:5]:
|
|
275
|
+
print(f" • {label}")
|
|
276
|
+
|
|
277
|
+
if not dry_run and orphaned_labels:
|
|
278
|
+
deleted_labels = []
|
|
279
|
+
for label in orphaned_labels:
|
|
280
|
+
if self.delete_repository_label(label):
|
|
281
|
+
deleted_labels.append(label)
|
|
282
|
+
return deleted_labels
|
|
283
|
+
|
|
284
|
+
return list(orphaned_labels)
|
|
285
|
+
|
|
286
|
+
except Exception as e:
|
|
287
|
+
print(f"⚠️ Error during orphan detection: {e}")
|
|
288
|
+
# Fallback to old pattern-based method
|
|
289
|
+
return self.cleanup_sha_labels(dry_run)
|
|
290
|
+
|
|
228
291
|
def create_or_update_label(self, name: str, color: str, description: str) -> bool:
|
|
229
292
|
"""Create or update a label with color and description"""
|
|
230
293
|
import urllib.parse
|
showtime/core/pull_request.py
CHANGED
|
@@ -325,7 +325,12 @@ class PullRequest:
|
|
|
325
325
|
)
|
|
326
326
|
|
|
327
327
|
# 3. Atomic claim for environment changes (PR-level lock)
|
|
328
|
-
if action_needed in [
|
|
328
|
+
if action_needed in [
|
|
329
|
+
"create_environment",
|
|
330
|
+
"rolling_update",
|
|
331
|
+
"auto_sync",
|
|
332
|
+
"destroy_environment",
|
|
333
|
+
]:
|
|
329
334
|
print(f"🔒 Claiming environment for {action_needed}...")
|
|
330
335
|
if not self._atomic_claim(target_sha, action_needed, dry_run_github):
|
|
331
336
|
print("❌ Claim failed - another job is active")
|
|
@@ -406,16 +411,20 @@ class PullRequest:
|
|
|
406
411
|
return SyncResult(success=True, action_taken=action_needed, show=new_show)
|
|
407
412
|
|
|
408
413
|
elif action_needed == "destroy_environment":
|
|
414
|
+
# Stop the current environment if it exists
|
|
409
415
|
if self.current_show:
|
|
410
416
|
print(f"🗑️ Destroying environment {self.current_show.sha}...")
|
|
411
417
|
self.current_show.stop(dry_run_github=dry_run_github, dry_run_aws=dry_run_aws)
|
|
412
418
|
print("☁️ AWS resources deleted")
|
|
413
419
|
self._post_cleanup_comment(self.current_show, dry_run_github)
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
420
|
+
else:
|
|
421
|
+
print("🗑️ No current environment to destroy")
|
|
422
|
+
|
|
423
|
+
# ALWAYS remove all circus labels for stop trigger, regardless of current_show
|
|
424
|
+
if not dry_run_github:
|
|
425
|
+
self.remove_showtime_labels()
|
|
426
|
+
print("🏷️ GitHub labels cleaned up")
|
|
427
|
+
print("✅ Environment destroyed")
|
|
419
428
|
return SyncResult(success=True, action_taken="destroy_environment")
|
|
420
429
|
|
|
421
430
|
else:
|
|
@@ -436,16 +445,18 @@ class PullRequest:
|
|
|
436
445
|
|
|
437
446
|
def stop_environment(self, **kwargs: Any) -> SyncResult:
|
|
438
447
|
"""Stop current environment (CLI stop command logic)"""
|
|
439
|
-
if not self.current_show:
|
|
440
|
-
return SyncResult(
|
|
441
|
-
success=True, action_taken="no_environment", error="No environment to stop"
|
|
442
|
-
)
|
|
443
|
-
|
|
444
448
|
try:
|
|
445
|
-
|
|
446
|
-
|
|
449
|
+
# Stop the current environment if it exists
|
|
450
|
+
if self.current_show:
|
|
451
|
+
self.current_show.stop(**kwargs)
|
|
452
|
+
print("☁️ AWS resources deleted")
|
|
453
|
+
else:
|
|
454
|
+
print("🗑️ No current environment to destroy")
|
|
455
|
+
|
|
456
|
+
# ALWAYS remove all circus labels for stop command, regardless of current_show
|
|
447
457
|
if not kwargs.get("dry_run_github", False):
|
|
448
458
|
self.remove_showtime_labels()
|
|
459
|
+
print("🏷️ GitHub labels cleaned up")
|
|
449
460
|
return SyncResult(success=True, action_taken="stopped")
|
|
450
461
|
except Exception as e:
|
|
451
462
|
return SyncResult(success=False, action_taken="stop_failed", error=str(e))
|
|
@@ -543,10 +554,14 @@ class PullRequest:
|
|
|
543
554
|
elif "showtime-trigger-stop" in trigger:
|
|
544
555
|
return "destroy_environment"
|
|
545
556
|
|
|
546
|
-
# No explicit triggers -
|
|
557
|
+
# No explicit triggers - only auto-create if there's ANY previous environment
|
|
547
558
|
if not target_show:
|
|
548
|
-
# Target SHA doesn't exist - create
|
|
549
|
-
|
|
559
|
+
# Target SHA doesn't exist - only create if there's any previous environment
|
|
560
|
+
if self.shows: # Any previous environment exists
|
|
561
|
+
return "create_environment"
|
|
562
|
+
else:
|
|
563
|
+
# No previous environments - don't auto-create without explicit trigger
|
|
564
|
+
return "no_action"
|
|
550
565
|
elif target_show.status == "failed":
|
|
551
566
|
# Target SHA failed - rebuild it
|
|
552
567
|
return "create_environment"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superset-showtime
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.4
|
|
4
4
|
Summary: 🎪 Apache Superset ephemeral environment management with circus tent emoji state tracking
|
|
5
5
|
Project-URL: Homepage, https://github.com/apache/superset-showtime
|
|
6
6
|
Project-URL: Documentation, https://superset-showtime.readthedocs.io/
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
showtime/__init__.py,sha256=
|
|
1
|
+
showtime/__init__.py,sha256=O8PG7VEz2VYlezufbPc7zRxajuNxLRaW7XTXnOYSki0,448
|
|
2
2
|
showtime/__main__.py,sha256=EVaDaTX69yIhCzChg99vqvFSCN4ELstEt7Mpb9FMZX8,109
|
|
3
|
-
showtime/cli.py,sha256=
|
|
3
|
+
showtime/cli.py,sha256=TLv9NaqPyewKJi9uCTZKWBijGelqunmsoSo7cyKajV4,31640
|
|
4
4
|
showtime/core/__init__.py,sha256=54hbdFNGrzuNMBdraezfjT8Zi6g221pKlJ9mREnKwCw,34
|
|
5
5
|
showtime/core/aws.py,sha256=uTjJAvEBQMyTccS93WZeNPhfeKQhJgOQQ0BJdnQjvCU,35007
|
|
6
6
|
showtime/core/emojis.py,sha256=arK0N5Q5FLkvOkci-lacb3WS56LTvY8NjYRqt_lhP9s,2188
|
|
7
7
|
showtime/core/git_validation.py,sha256=3dmSGpMDplDAmKWHUyoUEPgt3__8oTuBZxbfuhocT00,6831
|
|
8
|
-
showtime/core/github.py,sha256=
|
|
8
|
+
showtime/core/github.py,sha256=mSOqRLy2KMDhWUS37V2gJ-CQdeBpEqunBRKL10v5hxU,12268
|
|
9
9
|
showtime/core/github_messages.py,sha256=MfgwCukrEsWWesMsuL8saciDgP4nS-gijzu8DXr-Alg,7450
|
|
10
10
|
showtime/core/label_colors.py,sha256=gSe7EIMl4YjWkIgKHUvuaRSwgEB_B-NYQBxFFlF8Z3s,4065
|
|
11
|
-
showtime/core/pull_request.py,sha256=
|
|
11
|
+
showtime/core/pull_request.py,sha256=DCrTYz3Fu2Oh9FRgYTwncvzX7zy4Wa0BZsBwYa3nTpg,32669
|
|
12
12
|
showtime/core/show.py,sha256=sOgZvGXwdcNDsidF1F_XwPXlSeTb8-Zeqhqb8w1pqAM,9973
|
|
13
13
|
showtime/data/ecs-task-definition.json,sha256=d-NLkIhvr4C6AnwDfDIwUTx-6KFMH9wRkt6pVCbqZY4,2365
|
|
14
|
-
superset_showtime-0.
|
|
15
|
-
superset_showtime-0.
|
|
16
|
-
superset_showtime-0.
|
|
17
|
-
superset_showtime-0.
|
|
14
|
+
superset_showtime-0.6.4.dist-info/METADATA,sha256=SqFxH-mmg3jpLnOp2Gkl2AHJjewmga-nNtSe4HHk8bw,12052
|
|
15
|
+
superset_showtime-0.6.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
superset_showtime-0.6.4.dist-info/entry_points.txt,sha256=rDW7oZ57mqyBUS4N_3_R7bZNGVHB-104jwmY-hHC_ck,85
|
|
17
|
+
superset_showtime-0.6.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|