import requests import json import os import argparse from dotenv import load_dotenv # Cargar variables del archivo .env load_dotenv() # --- Configuración (obtenida de variables de entorno) --- GITEA_API_KEY = os.getenv("GITEA_API_KEY") GITEA_API_KEY_URL = os.getenv("GITEA_API_KEY_URL") GITEA_USERNAME = os.getenv("GITEA_USERNAME") GITEA_REPO_NAME = os.getenv("GITEA_REPO_NAME") # Extraer la URL base de Gitea de GITEA_API_KEY_URL GITEA_BASE_URL = GITEA_API_KEY_URL.split('/api/v1/')[0] def _make_gitea_request(method, endpoint, payload=None): """Helper function to make authenticated requests to Gitea API.""" api_url = f"{GITEA_BASE_URL}/api/v1/{endpoint}" headers = { "Accept": "application/json", "Authorization": f"token {GITEA_API_KEY}", "Content-Type": "application/json" } try: if method == "POST": response = requests.post(api_url, headers=headers, data=json.dumps(payload)) elif method == "PATCH": response = requests.patch(api_url, headers=headers, data=json.dumps(payload)) else: raise ValueError(f"Unsupported HTTP method: {method}") response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error en la solicitud {method} a {api_url}: {e}") if hasattr(e, 'response') and e.response is not None: print(f"Respuesta del servidor: {e.response.text}") raise def create_issue(title, body): """Creates a new issue in the Gitea repository.""" endpoint = f"repos/{GITEA_USERNAME}/{GITEA_REPO_NAME}/issues" payload = { "title": title, "body": body, "closed": False } print(f"Creando issue: '{title}'...") issue_data = _make_gitea_request("POST", endpoint, payload) print(f"Issue creado exitosamente:") print(f" Número: {issue_data['number']}") print(f" Título: {issue_data['title']}") print(f" URL: {issue_data['html_url']}") def create_pull_request(head_branch, base_branch, title, body): """Creates a new pull request in the Gitea repository.""" endpoint = f"repos/{GITEA_USERNAME}/{GITEA_REPO_NAME}/pulls" payload = { "head": head_branch, "base": base_branch, "title": title, "body": body } print(f"Creando Pull Request: '{title}' de '{head_branch}' a '{base_branch}'...") pr_data = _make_gitea_request("POST", endpoint, payload) print(f"Pull Request creado exitosamente:") print(f" Número: {pr_data['number']}") print(f" Título: {pr_data['title']}") print(f" URL: {pr_data['html_url']}") def comment_issue(issue_number, body): """Adds a comment to an existing issue.""" endpoint = f"repos/{GITEA_USERNAME}/{GITEA_REPO_NAME}/issues/{issue_number}/comments" payload = { "body": body } print(f"Añadiendo comentario al issue #{issue_number}...") _make_gitea_request("POST", endpoint, payload) print(f"Comentario añadido al issue #{issue_number} exitosamente.") def close_issue(issue_number): """Closes an existing issue.""" endpoint = f"repos/{GITEA_USERNAME}/{GITEA_REPO_NAME}/issues/{issue_number}" payload = { "state": "closed" } print(f"Cerrando issue #{issue_number}...") _make_gitea_request("PATCH", endpoint, payload) print(f"Issue #{issue_number} cerrado exitosamente.") def main(): parser = argparse.ArgumentParser(description="Helper CLI para interactuar con la API de Gitea.") subparsers = parser.add_subparsers(dest="command", help="Comandos disponibles") # Subparser para crear issue create_issue_parser = subparsers.add_parser("create-issue", help="Crea un nuevo issue.") create_issue_parser.add_argument("--title", required=True, help="Título del issue.") create_issue_parser.add_argument("--body", required=True, help="Cuerpo/descripción del issue (soporta multilínea con \n).") # Subparser para crear pull request create_pr_parser = subparsers.add_parser("create-pr", help="Crea un nuevo pull request.") create_pr_parser.add_argument("--head", required=True, help="Rama de origen (head branch).") create_pr_parser.add_argument("--base", required=True, help="Rama de destino (base branch).") create_pr_parser.add_argument("--title", required=True, help="Título del pull request.") create_pr_parser.add_argument("--body", required=True, help="Cuerpo/descripción del pull request (soporta multilínea con \n).") # Subparser para comentar issue comment_issue_parser = subparsers.add_parser("comment-issue", help="Añade un comentario a un issue existente.") comment_issue_parser.add_argument("--issue-number", type=int, required=True, help="Número del issue.") comment_issue_parser.add_argument("--body", required=True, help="Cuerpo del comentario (soporta multilínea con \n).") # Subparser para cerrar issue close_issue_parser = subparsers.add_parser("close-issue", help="Cierra un issue existente.") close_issue_parser.add_argument("--issue-number", type=int, required=True, help="Número del issue a cerrar.") args = parser.parse_args() if args.command == "create-issue": create_issue(args.title, args.body) elif args.command == "create-pr": create_pull_request(args.head, args.base, args.title, args.body) elif args.command == "comment-issue": comment_issue(args.issue_number, args.body) elif args.command == "close-issue": close_issue(args.issue_number) else: parser.print_help() if __name__ == "__main__": main()