|
15 | 15 | from recce_cloud import __version__ |
16 | 16 | from recce_cloud.artifact import get_adapter_type, verify_artifacts_path |
17 | 17 | from recce_cloud.ci_providers import CIDetector |
| 18 | +from recce_cloud.delete import ( |
| 19 | + delete_existing_session, |
| 20 | + delete_with_platform_apis, |
| 21 | +) |
18 | 22 | from recce_cloud.download import ( |
19 | 23 | download_from_existing_session, |
20 | 24 | download_with_platform_apis, |
@@ -432,6 +436,171 @@ def download(target_path, session_id, prod, dry_run, force): |
432 | 436 | download_with_platform_apis(console, token, ci_info, target_path, force) |
433 | 437 |
|
434 | 438 |
|
| 439 | +@cloud_cli.command() |
| 440 | +@click.option( |
| 441 | + "--session-id", |
| 442 | + envvar="RECCE_SESSION_ID", |
| 443 | + help="Session ID to delete. Required for non-CI workflows.", |
| 444 | +) |
| 445 | +@click.option( |
| 446 | + "--dry-run", |
| 447 | + is_flag=True, |
| 448 | + help="Show what would be deleted without actually deleting", |
| 449 | +) |
| 450 | +@click.option( |
| 451 | + "--force", |
| 452 | + "-f", |
| 453 | + is_flag=True, |
| 454 | + help="Skip confirmation prompt", |
| 455 | +) |
| 456 | +def delete(session_id, dry_run, force): |
| 457 | + """ |
| 458 | + Delete a Recce Cloud session. |
| 459 | +
|
| 460 | + Note: Deleting production sessions is not supported. To update production, |
| 461 | + upload a new session to overwrite it. Contact us if you need to delete |
| 462 | + a production session. |
| 463 | +
|
| 464 | + \b |
| 465 | + Authentication (auto-detected): |
| 466 | + - RECCE_API_TOKEN (for --session-id workflow) |
| 467 | + - GITHUB_TOKEN (GitHub Actions) |
| 468 | + - CI_JOB_TOKEN (GitLab CI) |
| 469 | +
|
| 470 | + \b |
| 471 | + Common Examples: |
| 472 | + # Delete current PR/MR session (in CI) |
| 473 | + recce-cloud delete |
| 474 | +
|
| 475 | + # Delete a specific session by ID |
| 476 | + recce-cloud delete --session-id abc123 |
| 477 | +
|
| 478 | + # Skip confirmation prompt |
| 479 | + recce-cloud delete --force |
| 480 | + """ |
| 481 | + console = Console() |
| 482 | + |
| 483 | + # 1. Auto-detect CI environment information |
| 484 | + console.rule("CI Environment Detection", style="blue") |
| 485 | + try: |
| 486 | + ci_info = CIDetector.detect() |
| 487 | + |
| 488 | + # Display detected CI information immediately |
| 489 | + if ci_info: |
| 490 | + info_table = [] |
| 491 | + if ci_info.platform: |
| 492 | + info_table.append(f"[cyan]Platform:[/cyan] {ci_info.platform}") |
| 493 | + |
| 494 | + if ci_info.repository: |
| 495 | + info_table.append(f"[cyan]Repository:[/cyan] {ci_info.repository}") |
| 496 | + |
| 497 | + # Only show session type and CR info for platform workflow |
| 498 | + if not session_id: |
| 499 | + if ci_info.session_type: |
| 500 | + info_table.append(f"[cyan]Session Type:[/cyan] {ci_info.session_type}") |
| 501 | + |
| 502 | + # Only show CR number and URL for CR sessions (not for prod) |
| 503 | + if ci_info.session_type == "cr" and ci_info.cr_number is not None: |
| 504 | + if ci_info.platform == "github-actions": |
| 505 | + info_table.append(f"[cyan]PR Number:[/cyan] {ci_info.cr_number}") |
| 506 | + elif ci_info.platform == "gitlab-ci": |
| 507 | + info_table.append(f"[cyan]MR Number:[/cyan] {ci_info.cr_number}") |
| 508 | + else: |
| 509 | + info_table.append(f"[cyan]CR Number:[/cyan] {ci_info.cr_number}") |
| 510 | + |
| 511 | + # Only show CR URL for CR sessions |
| 512 | + if ci_info.session_type == "cr" and ci_info.cr_url: |
| 513 | + if ci_info.platform == "github-actions": |
| 514 | + info_table.append(f"[cyan]PR URL:[/cyan] {ci_info.cr_url}") |
| 515 | + elif ci_info.platform == "gitlab-ci": |
| 516 | + info_table.append(f"[cyan]MR URL:[/cyan] {ci_info.cr_url}") |
| 517 | + else: |
| 518 | + info_table.append(f"[cyan]CR URL:[/cyan] {ci_info.cr_url}") |
| 519 | + |
| 520 | + for line in info_table: |
| 521 | + console.print(line) |
| 522 | + else: |
| 523 | + console.print("[yellow]No CI environment detected[/yellow]") |
| 524 | + except Exception as e: |
| 525 | + console.print(f"[yellow]Warning:[/yellow] Failed to detect CI environment: {e}") |
| 526 | + console.print("Continuing without CI metadata...") |
| 527 | + ci_info = None |
| 528 | + |
| 529 | + # 2. Handle dry-run mode (before authentication or API calls) |
| 530 | + if dry_run: |
| 531 | + console.rule("Dry Run Summary", style="yellow") |
| 532 | + console.print("[yellow]Dry run mode enabled - no actual deletion will be performed[/yellow]") |
| 533 | + console.print() |
| 534 | + |
| 535 | + # Display platform information if detected |
| 536 | + if ci_info and ci_info.platform: |
| 537 | + console.print("[cyan]Platform Information:[/cyan]") |
| 538 | + console.print(f" • Platform: {ci_info.platform}") |
| 539 | + if ci_info.repository: |
| 540 | + console.print(f" • Repository: {ci_info.repository}") |
| 541 | + if ci_info.session_type: |
| 542 | + console.print(f" • Session Type: {ci_info.session_type}") |
| 543 | + if ci_info.session_type == "cr" and ci_info.cr_number is not None: |
| 544 | + console.print(f" • CR Number: {ci_info.cr_number}") |
| 545 | + console.print() |
| 546 | + |
| 547 | + # Display delete summary |
| 548 | + console.print("[cyan]Delete Workflow:[/cyan]") |
| 549 | + if session_id: |
| 550 | + console.print(" • Delete specific session by ID") |
| 551 | + console.print(f" • Session ID: {session_id}") |
| 552 | + else: |
| 553 | + console.print(" • Auto-detect and delete PR/MR session") |
| 554 | + |
| 555 | + if ci_info and ci_info.platform in ["github-actions", "gitlab-ci"]: |
| 556 | + console.print(" • Platform-specific APIs will be used") |
| 557 | + else: |
| 558 | + console.print(" • [yellow]Warning: Platform not supported for auto-session discovery[/yellow]") |
| 559 | + |
| 560 | + console.print() |
| 561 | + console.print("[green]✓[/green] Dry run completed successfully") |
| 562 | + sys.exit(0) |
| 563 | + |
| 564 | + # 3. Confirmation prompt (unless --force is provided) |
| 565 | + if not force: |
| 566 | + console.print() |
| 567 | + if session_id: |
| 568 | + confirm_msg = f'Are you sure you want to delete session "{session_id}"?' |
| 569 | + else: |
| 570 | + confirm_msg = "Are you sure you want to delete the PR/MR session?" |
| 571 | + |
| 572 | + if not click.confirm(confirm_msg): |
| 573 | + console.print("[yellow]Aborted[/yellow]") |
| 574 | + sys.exit(0) |
| 575 | + |
| 576 | + # 4. Choose delete workflow based on whether session_id is provided |
| 577 | + if session_id: |
| 578 | + # Generic workflow: Delete from existing session using session ID |
| 579 | + # This workflow requires RECCE_API_TOKEN |
| 580 | + token = os.getenv("RECCE_API_TOKEN") |
| 581 | + if not token: |
| 582 | + console.print("[red]Error:[/red] No RECCE_API_TOKEN provided") |
| 583 | + console.print("Set RECCE_API_TOKEN environment variable for session-based delete") |
| 584 | + sys.exit(2) |
| 585 | + |
| 586 | + delete_existing_session(console, token, session_id) |
| 587 | + else: |
| 588 | + # Platform-specific workflow: Use platform APIs to find and delete session |
| 589 | + # This workflow MUST use CI job tokens (CI_JOB_TOKEN or GITHUB_TOKEN) |
| 590 | + if not ci_info or not ci_info.access_token: |
| 591 | + console.print("[red]Error:[/red] Platform-specific delete requires CI environment") |
| 592 | + console.print("Either run in GitHub Actions/GitLab CI or provide --session-id for generic delete") |
| 593 | + sys.exit(2) |
| 594 | + |
| 595 | + token = ci_info.access_token |
| 596 | + if ci_info.platform == "github-actions": |
| 597 | + console.print("[cyan]Info:[/cyan] Using GITHUB_TOKEN for platform-specific authentication") |
| 598 | + elif ci_info.platform == "gitlab-ci": |
| 599 | + console.print("[cyan]Info:[/cyan] Using CI_JOB_TOKEN for platform-specific authentication") |
| 600 | + |
| 601 | + delete_with_platform_apis(console, token, ci_info, prod=False) |
| 602 | + |
| 603 | + |
435 | 604 | @cloud_cli.command() |
436 | 605 | @click.option( |
437 | 606 | "--repo", |
|
0 commit comments