#!/usr/bin/env python3 """ Shared Jira config loading for g3fo-commit-jira scripts. Uses the same jira_upload.env / env vars as upload_attachment.py. """ import base64 import os from pathlib import Path from typing import Dict, Optional CONFIG_FILENAME = "jira_upload.env" def find_config_file(explicit_path: Optional[str], script_dir: Path) -> Optional[Path]: if explicit_path: p = Path(explicit_path) return p if p.exists() and p.is_file() else None cwd_file = Path.cwd() / CONFIG_FILENAME if cwd_file.exists(): return cwd_file script_dir_file = script_dir / CONFIG_FILENAME if script_dir_file.exists(): return script_dir_file parent_skill = script_dir.parent / CONFIG_FILENAME if parent_skill.exists(): return parent_skill return None def load_config(config_path: Optional[str] = None, script_dir: Optional[Path] = None) -> Dict[str, str]: """Load KEY=VALUE from jira_upload.env. Env vars override file values.""" if script_dir is None: script_dir = Path(__file__).resolve().parent path = find_config_file(config_path, script_dir) out: Dict[str, str] = {} if path: with open(path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if "=" in line: k, _, v = line.partition("=") out[k.strip()] = v.strip().strip('"').strip("'") for key in ("JIRA_BASE_URL", "JIRA_EMAIL", "JIRA_API_TOKEN"): if key in os.environ: out[key] = os.environ[key] return out def require_credentials(cfg: Dict[str, str]) -> tuple: base_url = (cfg.get("JIRA_BASE_URL") or "https://n2nafe.atlassian.net").rstrip("/") email = cfg.get("JIRA_EMAIL") token = cfg.get("JIRA_API_TOKEN") if not email or not token: raise ValueError( "Missing JIRA_EMAIL or JIRA_API_TOKEN. " f"Please configure {CONFIG_FILENAME} file first. " f"You can apply for API token at: https://id.atlassian.com/manage-profile/security/api-tokens" ) return base_url, email, token def auth_header(email: str, token: str) -> str: return base64.b64encode(f"{email}:{token}".encode()).decode() def session_headers(email: str, token: str, json_body: bool = True) -> Dict[str, str]: h = { "Authorization": f"Basic {auth_header(email, token)}", "Accept": "application/json", } if json_body: h["Content-Type"] = "application/json" return h