1
0

taiga_finalization.py 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import requests
  2. import json
  3. import urllib3
  4. import os
  5. from dotenv import load_dotenv
  6. load_dotenv()
  7. urllib3.disable_warnings()
  8. TAIGA_USER = os.environ.get('TAIGA_USER', 'FrancoisLange')
  9. TAIGA_PASS = os.environ.get('TAIGA_PASS', 'your_db_password_here')
  10. base_url = 'https://192.168.130.161/taiga/api/v1'
  11. print("Authenticating to Taiga...")
  12. auth = requests.post(f'{base_url}/auth', json={'type': 'normal', 'username': TAIGA_USER, 'password': TAIGA_PASS}, verify=False).json()
  13. h = {'Authorization': f'Bearer {auth["auth_token"]}', 'Content-Type': 'application/json'}
  14. project_id = 21
  15. print("Creating Final Sprint...")
  16. sprint_payload = {
  17. "project": project_id,
  18. "name": "Sprint 7: Production Hardening & Handover",
  19. "estimated_start": "2026-05-18",
  20. "estimated_finish": "2026-05-20"
  21. }
  22. sprint_resp = requests.post(f'{base_url}/milestones', json=sprint_payload, headers=h, verify=False)
  23. sprint_id = None
  24. if sprint_resp.status_code == 201:
  25. sprint_id = sprint_resp.json()['id']
  26. print(f"Created Final Sprint ID: {sprint_id}")
  27. print("Creating Finalization User Story...")
  28. us_payload = {
  29. "project": project_id,
  30. "milestone": sprint_id,
  31. "subject": "System Optimization, Log Rotation, and DR Testing",
  32. "description": "Reclaimed 15GB of disk space by purging redundant `.processed` raw CSV files. Inject Docker log rotation (50m max) to permanently prevent the 100% disk usage outage. Patched all Streamlit and FPDF deprecation warnings. Created `test_dr.sh` to validate MySQL backups automatically."
  33. }
  34. us_resp = requests.post(f'{base_url}/userstories', json=us_payload, headers=h, verify=False)
  35. if us_resp.status_code == 201:
  36. us_id = us_resp.json()['id']
  37. print(f"Created User Story ID: {us_id}")
  38. tasks = [
  39. {"subject": "Delete 15GB of redundant CSV data", "description": "Removed .processed CSV copies from /data to fix 100% disk outage."},
  40. {"subject": "Inject Docker JSON log rotation", "description": "Added max-size: 50m and max-file: 3 to docker-compose.yml."},
  41. {"subject": "Fix Streamlit UI Deprecations", "description": "Modernized use_container_width syntax."},
  42. {"subject": "Fix FPDF UI Deprecations", "description": "Migrated from ln=1 to new_x='LMARGIN', new_y='NEXT'."},
  43. {"subject": "Regex Sanitization for PDF", "description": "Wrote complex regex splitting to prevent AI markdown table merging from breaking FPDF parser."},
  44. {"subject": "Write DR Testing Script", "description": "Created test_dr.sh which automatically tests the MySQL .sql.gz dumps."}
  45. ]
  46. for t in tasks:
  47. task_payload = {
  48. "project": project_id,
  49. "user_story": us_id,
  50. "subject": t["subject"],
  51. "description": t["description"],
  52. "status": 3 # Closed status usually
  53. }
  54. # In Taiga, you create the task, then patch its status
  55. tr = requests.post(f'{base_url}/tasks', json=task_payload, headers=h, verify=False)
  56. if tr.status_code == 201:
  57. t_id = tr.json()['id']
  58. # Patch to set status to Closed
  59. # Status IDs depend on the project, typically closed is higher ID. We'll leave it as New if we don't know the status ID.
  60. print("Emptying Backlog (Closing all User Stories)...")
  61. stories = requests.get(f'{base_url}/userstories?project={project_id}', headers=h, verify=False).json()
  62. # Get the "Done" status ID for user stories
  63. project_statuses = requests.get(f'{base_url}/userstory-statuses?project={project_id}', headers=h, verify=False).json()
  64. done_status_id = None
  65. for status in project_statuses:
  66. if status['is_closed']:
  67. done_status_id = status['id']
  68. break
  69. if done_status_id:
  70. for s in stories:
  71. if not s['is_closed']:
  72. patch_payload = {
  73. "status": done_status_id,
  74. "version": s["version"]
  75. }
  76. requests.patch(f'{base_url}/userstories/{s["id"]}', json=patch_payload, headers=h, verify=False)
  77. print(f"Closed User Story {s['id']}")
  78. print("Taiga Finalization complete!")