superset-showtime 0.2.8__py3-none-any.whl → 0.4.2__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/core/show.py ADDED
@@ -0,0 +1,279 @@
1
+ """
2
+ 🎪 Show class - Individual ephemeral environment management
3
+
4
+ Single environment operations: Docker build, AWS deployment, state transitions.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+ from datetime import datetime
9
+ from typing import List, Optional
10
+
11
+
12
+ # Import interfaces for singleton access
13
+ # Note: These will be imported when the module loads, creating singletons
14
+ def get_interfaces(): # type: ignore
15
+ """Lazy-load interfaces to avoid circular imports"""
16
+ from .aws import AWSInterface
17
+ from .github import GitHubInterface
18
+
19
+ return GitHubInterface(), AWSInterface()
20
+
21
+
22
+ @dataclass
23
+ class Show:
24
+ """Single ephemeral environment state from circus labels"""
25
+
26
+ pr_number: int
27
+ sha: str # 7-char commit SHA
28
+ status: str # building, built, deploying, running, updating, failed
29
+ ip: Optional[str] = None # Environment IP address
30
+ created_at: Optional[str] = None # ISO timestamp
31
+ ttl: str = "24h" # 24h, 48h, close, etc.
32
+ requested_by: Optional[str] = None # GitHub username
33
+
34
+ @property
35
+ def aws_service_name(self) -> str:
36
+ """Deterministic ECS service name: pr-{pr_number}-{sha}"""
37
+ return f"pr-{self.pr_number}-{self.sha}"
38
+
39
+ @property
40
+ def ecs_service_name(self) -> str:
41
+ """ECS service name with -service suffix"""
42
+ return f"{self.aws_service_name}-service"
43
+
44
+ @property
45
+ def aws_image_tag(self) -> str:
46
+ """Deterministic Docker image tag: pr-{pr_number}-{sha}-ci"""
47
+ return f"pr-{self.pr_number}-{self.sha}-ci"
48
+
49
+ @property
50
+ def short_sha(self) -> str:
51
+ """Return the short SHA (already short)"""
52
+ return self.sha
53
+
54
+ @property
55
+ def is_running(self) -> bool:
56
+ """Check if environment is currently running"""
57
+ return self.status == "running"
58
+
59
+ @property
60
+ def is_building(self) -> bool:
61
+ """Check if environment is currently building"""
62
+ return self.status == "building"
63
+
64
+ @property
65
+ def is_built(self) -> bool:
66
+ """Check if environment is built (Docker complete, ready for deploy)"""
67
+ return self.status == "built"
68
+
69
+ @property
70
+ def is_deploying(self) -> bool:
71
+ """Check if environment is currently deploying to AWS"""
72
+ return self.status == "deploying"
73
+
74
+ @property
75
+ def is_updating(self) -> bool:
76
+ """Check if environment is currently updating"""
77
+ return self.status == "updating"
78
+
79
+ def needs_update(self, latest_sha: str) -> bool:
80
+ """Check if environment needs update to latest SHA"""
81
+ return self.sha != latest_sha[:7]
82
+
83
+ def is_expired(self, max_age_hours: int) -> bool:
84
+ """Check if this environment is expired based on age"""
85
+ if not self.created_at:
86
+ return False
87
+
88
+ try:
89
+ from datetime import datetime, timedelta
90
+
91
+ created_time = datetime.fromisoformat(self.created_at.replace("-", ":"))
92
+ expiry_time = created_time + timedelta(hours=max_age_hours)
93
+ return datetime.now() > expiry_time
94
+ except (ValueError, AttributeError):
95
+ return False # If we can't parse, assume not expired
96
+
97
+ def to_circus_labels(self) -> List[str]:
98
+ """Convert show state to circus tent emoji labels (per-SHA format)"""
99
+ if not self.created_at:
100
+ self.created_at = datetime.utcnow().strftime("%Y-%m-%dT%H-%M")
101
+
102
+ labels = [
103
+ f"🎪 {self.sha} 🚦 {self.status}", # SHA-first status
104
+ f"🎪 🎯 {self.sha}", # Active pointer (no value)
105
+ f"🎪 {self.sha} 📅 {self.created_at}", # SHA-first timestamp
106
+ f"🎪 {self.sha} ⌛ {self.ttl}", # SHA-first TTL
107
+ ]
108
+
109
+ if self.ip:
110
+ labels.append(f"🎪 {self.sha} 🌐 {self.ip}:8080")
111
+
112
+ if self.requested_by:
113
+ labels.append(f"🎪 {self.sha} 🤡 {self.requested_by}")
114
+
115
+ return labels
116
+
117
+ def build_docker(self, dry_run: bool = False) -> None:
118
+ """Build Docker image for this environment (atomic operation)"""
119
+ if not dry_run:
120
+ self._build_docker_image() # Raises on failure
121
+
122
+ def deploy_aws(self, dry_run: bool = False) -> None:
123
+ """Deploy to AWS (atomic operation)"""
124
+ github, aws = get_interfaces()
125
+
126
+ if not dry_run:
127
+ result = aws.create_environment(
128
+ pr_number=self.pr_number,
129
+ sha=self.sha + "0" * (40 - len(self.sha)), # Convert to full SHA
130
+ github_user=self.requested_by or "unknown",
131
+ )
132
+
133
+ if not result.success:
134
+ raise Exception(f"AWS deployment failed: {result.error}")
135
+
136
+ # Update with deployment results
137
+ self.ip = result.ip
138
+ else:
139
+ # Mock successful deployment for dry-run
140
+ self.ip = "52.1.2.3"
141
+
142
+ def stop(self, dry_run_github: bool = False, dry_run_aws: bool = False) -> None:
143
+ """Stop this environment (cleanup AWS resources)
144
+
145
+ Raises:
146
+ Exception: On cleanup failure
147
+ """
148
+ github, aws = get_interfaces()
149
+
150
+ # Delete AWS resources (pure technical work)
151
+ if not dry_run_aws:
152
+ success = aws.delete_environment(self.aws_service_name, self.pr_number)
153
+ if not success:
154
+ raise Exception(f"Failed to delete AWS service: {self.aws_service_name}")
155
+
156
+ # No comments - PullRequest handles that!
157
+
158
+ def _build_docker_image(self) -> None:
159
+ """Build Docker image for this environment"""
160
+ import os
161
+ import platform
162
+ import subprocess
163
+
164
+ tag = f"apache/superset:pr-{self.pr_number}-{self.sha}-ci"
165
+
166
+ # Detect if running in CI environment
167
+ is_ci = bool(os.getenv("GITHUB_ACTIONS") or os.getenv("CI"))
168
+
169
+ # Base command
170
+ cmd = [
171
+ "docker",
172
+ "buildx",
173
+ "build",
174
+ "--push",
175
+ "--platform",
176
+ "linux/amd64",
177
+ "--target",
178
+ "ci",
179
+ "--build-arg",
180
+ "INCLUDE_CHROMIUM=false",
181
+ "--build-arg",
182
+ "LOAD_EXAMPLES_DUCKDB=true",
183
+ "-t",
184
+ tag,
185
+ ".",
186
+ ]
187
+
188
+ # Add caching based on environment
189
+ if is_ci:
190
+ # Full registry caching in CI (Docker driver supports it)
191
+ cmd.extend([
192
+ "--cache-from",
193
+ "type=registry,ref=apache/superset-cache:3.10-slim-bookworm",
194
+ "--cache-to",
195
+ "type=registry,mode=max,ref=apache/superset-cache:3.10-slim-bookworm",
196
+ ])
197
+ print("🐳 CI environment: Using full registry caching")
198
+ else:
199
+ # Local build: cache-from only (no cache export)
200
+ cmd.extend([
201
+ "--cache-from",
202
+ "type=registry,ref=apache/superset-cache:3.10-slim-bookworm",
203
+ ])
204
+ print("🐳 Local environment: Using cache-from only (no export)")
205
+
206
+ # Add --load only when building for native architecture or explicitly requested
207
+ # Intel Mac/Linux can load linux/amd64, Apple Silicon cannot
208
+ native_x86 = platform.machine() in ("x86_64", "AMD64")
209
+ force_load = os.getenv("DOCKER_LOAD", "false").lower() == "true"
210
+
211
+ if native_x86 or force_load:
212
+ cmd.insert(-1, "--load") # Insert before the "." argument
213
+ print("🐳 Will load image to local Docker daemon (native x86_64 platform)")
214
+ else:
215
+ print("🐳 Cross-platform build - pushing to registry only (no local load)")
216
+
217
+ print(f"🐳 Building Docker image: {tag}")
218
+
219
+ # Stream output in real-time
220
+ process = subprocess.Popen(
221
+ cmd,
222
+ stdout=subprocess.PIPE,
223
+ stderr=subprocess.STDOUT,
224
+ text=True,
225
+ bufsize=1,
226
+ universal_newlines=True,
227
+ )
228
+
229
+ if process.stdout:
230
+ for line in process.stdout:
231
+ print(f"🐳 {line.rstrip()}")
232
+
233
+ return_code = process.wait(timeout=3600)
234
+ if return_code != 0:
235
+ raise Exception(f"Docker build failed with exit code: {return_code}")
236
+
237
+ @classmethod
238
+ def from_circus_labels(cls, pr_number: int, labels: List[str], sha: str) -> Optional["Show"]:
239
+ """Create Show from circus tent labels for specific SHA"""
240
+ show_data = {
241
+ "pr_number": pr_number,
242
+ "sha": sha,
243
+ "status": "building", # default
244
+ }
245
+
246
+ for label in labels:
247
+ if not label.startswith("🎪"):
248
+ continue
249
+
250
+ parts = label.split(" ")
251
+ if len(parts) < 3:
252
+ continue
253
+
254
+ # Per-SHA format: 🎪 {sha} {emoji} {value}
255
+ if parts[1] == sha: # This label is for our SHA
256
+ emoji = parts[2]
257
+ value = " ".join(parts[3:]) if len(parts) > 3 else ""
258
+
259
+ if emoji == "🚦": # Status
260
+ show_data["status"] = value
261
+ elif emoji == "📅": # Timestamp
262
+ show_data["created_at"] = value
263
+ elif emoji == "🌐": # IP with port
264
+ show_data["ip"] = value.replace(":8080", "") # Remove port for storage
265
+ elif emoji == "⌛": # TTL
266
+ show_data["ttl"] = value
267
+ elif emoji == "🤡": # User (clown!)
268
+ show_data["requested_by"] = value
269
+
270
+ # Only return Show if we found relevant labels for this SHA
271
+ if any(label.endswith(f" {sha}") for label in labels if "🎯" in label or "🏗️" in label):
272
+ return cls(**show_data) # type: ignore[arg-type]
273
+
274
+ return None
275
+
276
+
277
+ def short_sha(full_sha: str) -> str:
278
+ """Convert full SHA to short SHA (7 chars)"""
279
+ return full_sha[:7]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superset-showtime
3
- Version: 0.2.8
3
+ Version: 0.4.2
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/
@@ -49,6 +49,7 @@ Provides-Extra: azure
49
49
  Requires-Dist: azure-mgmt-containerinstance>=10.0.0; extra == 'azure'
50
50
  Requires-Dist: azure-storage-blob>=12.0.0; extra == 'azure'
51
51
  Provides-Extra: dev
52
+ Requires-Dist: boto3-stubs[ec2,ecr,ecs]>=1.40.0; extra == 'dev'
52
53
  Requires-Dist: build>=1.0.0; extra == 'dev'
53
54
  Requires-Dist: mypy>=1.0.0; extra == 'dev'
54
55
  Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
@@ -113,9 +114,34 @@ Superset Showtime is a CLI tool designed primarily for **GitHub Actions** to man
113
114
  🎪 abc123f 🌐 52-1-2-3 # Available at http://52.1.2.3:8080
114
115
  ```
115
116
 
116
- ## 📊 For Maintainers (CLI Operations)
117
+ ### 🔄 Showtime Workflow
118
+
119
+ ```mermaid
120
+ flowchart TD
121
+ A[User adds 🎪 ⚡ trigger-start] --> B[GitHub Actions: sync]
122
+ B --> C{Current state?}
123
+
124
+ C -->|No environment| D[🔒 Claim: Remove trigger + Set building]
125
+ C -->|Running + new SHA| E[🔒 Claim: Remove trigger + Set building]
126
+ C -->|Already building| F[❌ Exit: Another job active]
127
+ C -->|No triggers| G[❌ Exit: Nothing to do]
128
+
129
+ D --> H[📋 State: building]
130
+ E --> H
131
+ H --> I[🐳 Docker build]
132
+ I -->|Success| J[📋 State: built]
133
+ I -->|Fail| K[📋 State: failed]
134
+
135
+ J --> L[📋 State: deploying]
136
+ L --> M[☁️ AWS Deploy]
137
+ M -->|Success| N[📋 State: running]
138
+ M -->|Fail| O[📋 State: failed]
139
+
140
+ N --> P[🎪 Environment ready!]
141
+
142
+ Q[User adds 🎪 🛑 trigger-stop] --> R[🧹 Cleanup AWS + Remove labels]
143
+ ```
117
144
 
118
- > **Note**: CLI is mainly for debugging or developing Showtime itself. Primary interface is GitHub labels above.
119
145
 
120
146
  **Install CLI for debugging:**
121
147
  ```bash
@@ -132,11 +158,11 @@ showtime labels # Complete label reference
132
158
 
133
159
  **Testing/development:**
134
160
  ```bash
135
- showtime start 1234 --dry-run-aws # Test without AWS costs
136
- showtime test-lifecycle 1234 # Full workflow simulation
161
+ showtime sync 1234 --dry-run-aws --dry-run-docker # Test without costs
162
+ showtime cleanup --dry-run --older-than 1h # Test cleanup logic
137
163
  ```
138
164
 
139
- > **Dependency**: This CLI coordinates with Superset's existing GitHub Actions build infrastructure. It orchestrates environments but relies on Superset's build workflows for container creation.
165
+ > **Architecture**: This CLI implements ACID-style atomic transactions with direct Docker integration. It handles complete environment lifecycle from Docker build to AWS deployment with race condition prevention.
140
166
 
141
167
  ## 🎪 Complete Label Reference
142
168
 
@@ -229,129 +255,38 @@ You'll see:
229
255
 
230
256
  ### GitHub Actions Integration
231
257
 
232
- Showtime is designed to be called by Superset's GitHub Actions workflows:
233
-
234
- ```yaml
235
- # .github/workflows/showtime.yml - Integrates with Superset's existing build workflows
236
- on:
237
- pull_request_target:
238
- types: [labeled, unlabeled, synchronize]
258
+ **🎯 Live Workflow**: [showtime-trigger.yml](https://github.com/apache/superset/actions/workflows/showtime-trigger.yml)
239
259
 
240
- jobs:
241
- showtime-handler:
242
- if: contains(github.event.label.name, '🎪')
243
- steps:
244
- - name: Install Showtime from PyPI
245
- run: pip install superset-showtime
260
+ **How it works:**
261
+ - Triggers on PR label changes, commits, and closures
262
+ - Installs `superset-showtime` from PyPI (trusted code, not PR code)
263
+ - Runs `showtime sync` to handle trigger processing and deployments
264
+ - Supports manual testing via `workflow_dispatch` with specific SHA override
246
265
 
247
- - name: Process circus triggers
248
- run: python -m showtime handle-trigger ${{ github.event.pull_request.number }}
249
- ```
250
-
251
- **Integration approach:**
252
- - **Coordinates with Superset builds** - Uses existing container build workflows
253
- - **Runs trusted code** (from PyPI, not PR code)
254
- - **Simple orchestration logic** (install CLI and run commands)
255
- - **Leverages existing infrastructure** - Same AWS resources and permissions
256
-
257
- ## 🛠️ Installation & Setup
258
-
259
- ### For Contributors (GitHub Labels Only)
260
- No installation needed! Just use GitHub labels to trigger environments.
261
-
262
- ### For Maintainers (Manual CLI Operations)
263
-
264
- **Install CLI for debugging/testing:**
266
+ **Commands used:**
265
267
  ```bash
266
- pip install superset-showtime
267
- export GITHUB_TOKEN=your_personal_access_token
268
+ showtime sync PR_NUMBER --check-only # Determine build_needed + target_sha
269
+ showtime sync PR_NUMBER --sha SHA # Execute atomic claim + build + deploy
268
270
  ```
269
271
 
270
- **Manual operations:**
271
- ```bash
272
- showtime list # Monitor all active environments
273
- showtime status 1234 # Debug specific environment
274
- showtime labels # Reference complete label system
275
- ```
276
-
277
- ### For Repository Integration (GitHub Actions)
278
-
279
- **1. Install GitHub workflows:**
280
- Copy `workflows-reference/showtime-trigger.yml` and `workflows-reference/showtime-cleanup.yml` to Superset's `.github/workflows/`.
281
-
282
- **2. Configure secrets (already exist in Superset):**
283
- - `AWS_ACCESS_KEY_ID`
284
- - `AWS_SECRET_ACCESS_KEY`
285
- - `GITHUB_TOKEN`
286
-
287
- **3. Dependencies:**
288
- Showtime coordinates with Superset's existing build infrastructure - no additional setup needed.
272
+ ## 🛠️ CLI Usage
289
273
 
290
- ## 📊 CLI Reference (For Development/Debugging)
274
+ The CLI is primarily used by GitHub Actions, but available for debugging and advanced users:
291
275
 
292
- > **Primary Interface**: Use GitHub labels in PR interface. CLI is mainly for maintainers debugging or developing Showtime itself.
293
-
294
- ### Debugging Commands
295
276
  ```bash
296
- showtime list # Monitor all environments
297
- showtime status 1234 # Debug specific environment
298
- showtime labels # Complete label reference
299
- showtime test-lifecycle 1234 # Full workflow simulation
300
- ```
277
+ pip install superset-showtime
278
+ export GITHUB_TOKEN=your_token
301
279
 
302
- ### Manual Operations (Advanced)
303
- ```bash
304
- showtime start 1234 # Manually create environment
305
- showtime start 1234 --sha abc123f # Create environment (specific SHA)
306
- showtime stop 1234 # Manually delete environment
307
- showtime sync 1234 # Force sync to desired state
308
- showtime cleanup --respect-ttl # Manual cleanup
280
+ # Core commands:
281
+ showtime sync PR_NUMBER # Sync to desired state (main command)
282
+ showtime start PR_NUMBER # Create new environment
283
+ showtime stop PR_NUMBER # Delete environment
284
+ showtime status PR_NUMBER # Show current state
285
+ showtime list # List all environments
286
+ showtime cleanup --older-than 48h # Clean up expired environments
309
287
  ```
310
288
 
311
- ### GitHub Actions Commands
312
- ```bash
313
- showtime handle-trigger 1234 # Process trigger labels (called by GHA)
314
- showtime cleanup --older-than 48h # Scheduled cleanup (called by GHA)
315
- ```
316
289
 
317
- ## 🎪 Benefits for Superset
318
-
319
- ### For Contributors
320
- - **🎯 Simple workflow** - Just add/remove GitHub labels
321
- - **👀 Visual feedback** - See environment status in PR labels
322
- - **⚡ Automatic updates** - New commits update environments automatically
323
- - **🔧 Configuration testing** - Test config changes through code commits
324
-
325
- ### For Maintainers
326
- - **📊 Complete visibility** - `showtime list` shows all environments
327
- - **🧹 Easy cleanup** - Automatic expired environment cleanup
328
- - **🔍 Better debugging** - Clear state in labels, comprehensive CLI
329
- - **💰 Cost savings** - No duplicate environments, proper cleanup
330
-
331
- ### For Operations
332
- - **📝 Simpler workflows** - Replace complex GHA scripts with simple CLI calls
333
- - **🔒 Same security model** - No new permissions needed
334
- - **🎯 Deterministic** - Predictable AWS resource naming
335
- - **🚨 Monitoring ready** - 48h maximum lifetime, scheduled cleanup
336
-
337
- ## 🏗️ Architecture
338
-
339
- ### State Management
340
- All state lives in **GitHub labels** - no external databases needed:
341
- - **Trigger labels** (`🎪 trigger-*`) - Commands that get processed and removed
342
- - **State labels** (`🎪 🚦 *`) - Current environment status, managed by CLI
343
-
344
- ### AWS Resources
345
- Deterministic naming enables reliable cleanup:
346
- - **ECS Service:** `pr-{pr_number}-{sha}` (e.g., `pr-1234-abc123f`)
347
- - **ECR Image:** `pr-{pr_number}-{sha}-ci` (e.g., `pr-1234-abc123f-ci`)
348
-
349
- ### Rolling Updates
350
- Zero-downtime updates by running multiple environments:
351
- 1. Keep old environment serving traffic
352
- 2. Build new environment in parallel
353
- 3. Switch traffic when new environment is healthy
354
- 4. Clean up old environment
355
290
 
356
291
  ## 🤝 Contributing
357
292
 
@@ -359,11 +294,11 @@ Zero-downtime updates by running multiple environments:
359
294
 
360
295
  **Test with real PRs safely:**
361
296
  ```bash
362
- # Test label management without AWS costs:
363
- showtime start YOUR_PR_NUMBER --dry-run-aws --aws-sleep 10
297
+ # Test full workflow without costs:
298
+ showtime sync YOUR_PR_NUMBER --dry-run-aws --dry-run-docker
364
299
 
365
- # Test full lifecycle:
366
- showtime test-lifecycle YOUR_PR_NUMBER --real-github
300
+ # Test cleanup logic:
301
+ showtime cleanup --dry-run --older-than 24h
367
302
  ```
368
303
 
369
304
  ### Development Setup
@@ -0,0 +1,16 @@
1
+ showtime/__init__.py,sha256=jzoTTK9K3uRo5GuAPaej-89Ny35OFYmHBR3FTQ7MiVk,448
2
+ showtime/__main__.py,sha256=EVaDaTX69yIhCzChg99vqvFSCN4ELstEt7Mpb9FMZX8,109
3
+ showtime/cli.py,sha256=faFM6pe3gz49_1KrzUeri7dQffqz4WP92JmGxPaIOC0,25249
4
+ showtime/core/__init__.py,sha256=54hbdFNGrzuNMBdraezfjT8Zi6g221pKlJ9mREnKwCw,34
5
+ showtime/core/aws.py,sha256=REeZ6_1C9f6mBchBAGa1MeDJeZIwir4IJ92HLRcK5ok,32636
6
+ showtime/core/emojis.py,sha256=MHEDuPIdfNiop4zbNLuviz3eY05QiftYSHHCVbkfKhw,2129
7
+ showtime/core/github.py,sha256=uETvKDO2Yhpqg3fxLtrKaCuZR3b-1LVmgnf5aLcqrAQ,9988
8
+ showtime/core/github_messages.py,sha256=MfgwCukrEsWWesMsuL8saciDgP4nS-gijzu8DXr-Alg,7450
9
+ showtime/core/label_colors.py,sha256=efhbFnz_3nqEnEqmgyF6_hZbxtCu_fmb68BIIUpSsnk,3895
10
+ showtime/core/pull_request.py,sha256=Yxc7Oy0dkvQQm3DbwUKbiCAW0wEivM8U2j5vSRwIDxE,20475
11
+ showtime/core/show.py,sha256=BRMH_Z53UfK0VXAMHfzS0u7_s0h634VKTMzWMniRNsg,9759
12
+ showtime/data/ecs-task-definition.json,sha256=0ZaE0FZ8IWduXd2RyscMhXeVgxyym6qtjH02CK9mXBI,2235
13
+ superset_showtime-0.4.2.dist-info/METADATA,sha256=h_RweT3LG7UW7HLTx49Gv26ulSJUV2c-YVULpYm_gw8,12052
14
+ superset_showtime-0.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
+ superset_showtime-0.4.2.dist-info/entry_points.txt,sha256=rDW7oZ57mqyBUS4N_3_R7bZNGVHB-104jwmY-hHC_ck,85
16
+ superset_showtime-0.4.2.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- """Showtime CLI commands"""
@@ -1,40 +0,0 @@
1
- """
2
- 🎪 Start show command - Create ephemeral environments
3
- """
4
-
5
- from dataclasses import dataclass
6
- from typing import Optional
7
-
8
-
9
- @dataclass
10
- class StartResult:
11
- """Result of starting a show"""
12
-
13
- success: bool
14
- url: Optional[str] = None
15
- error: Optional[str] = None
16
-
17
-
18
- def start_show(
19
- pr_number: int, sha: Optional[str] = None, ttl: str = "24h", size: str = "standard"
20
- ) -> StartResult:
21
- """
22
- Start the show! Create ephemeral environment for PR
23
-
24
- Args:
25
- pr_number: PR number to create environment for
26
- sha: Specific commit SHA (default: latest)
27
- ttl: Time to live (24h, 48h, 1w, close)
28
- size: Environment size (standard, large)
29
-
30
- Returns:
31
- StartResult with success status and details
32
- """
33
- # TODO: Implement environment creation
34
- # 1. Get latest SHA if not provided
35
- # 2. Create circus labels
36
- # 3. Build Docker image
37
- # 4. Deploy to ECS
38
- # 5. Update labels with running state
39
-
40
- return StartResult(success=False, error="Not yet implemented")