diff --git a/.github/scripts/update_currencies.py b/.github/scripts/update_currencies.py index 8de6518d..b546fe41 100644 --- a/.github/scripts/update_currencies.py +++ b/.github/scripts/update_currencies.py @@ -11,12 +11,14 @@ API_URL = 'https://restcountries.com/v3.1/all?fields=name,common,currencies' SAVE_PATH = Path('backend/internal/core/currencies/currencies.json') TIMEOUT = 10 # seconds + def setup_logging(): logging.basicConfig( level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s' ) + def fetch_currencies(): session = requests.Session() retries = Retry( @@ -32,19 +34,19 @@ def fetch_currencies(): resp.raise_for_status() except requests.exceptions.RequestException as e: logging.error("API request failed: %s", e) - return None + return None # signal fatal try: countries = resp.json() except ValueError as e: logging.error("Failed to parse JSON response: %s", e) - return None + return None # signal fatal - result = [] + results = [] for country in countries: country_name = country.get('name', {}).get('common') or "Unknown" for code, info in country.get('currencies', {}).items(): - result.append({ + results.append({ 'code': code, 'local': country_name, 'symbol': info.get('symbol', ''), @@ -52,7 +54,8 @@ def fetch_currencies(): }) # sort by country name for consistency - return sorted(result, key=lambda x: x['local'].lower()) + return sorted(results, key=lambda x: x['local'].lower()) + def load_existing(path: Path): if not path.exists(): @@ -64,36 +67,40 @@ def load_existing(path: Path): logging.warning("Could not load existing file (%s): %s", path, e) return [] + def save_currencies(data, path: Path): path.parent.mkdir(parents=True, exist_ok=True) - try: - with path.open('w', encoding='utf-8') as f: - json.dump(data, f, ensure_ascii=False, indent=4) - logging.info("Wrote %d entries to %s", len(data), path) - except IOError as e: - logging.error("Failed to write file: %s", e) - sys.exit(1) + with path.open('w', encoding='utf-8') as f: + json.dump(data, f, ensure_ascii=False, indent=4) + logging.info("Wrote %d entries to %s", len(data), path) + def main(): setup_logging() - logging.info("Starting currency update") + logging.info("🔄 Starting currency update") existing = load_existing(SAVE_PATH) new = fetch_currencies() + # Fatal API / parse error → exit non-zero so the workflow will fail if new is None: logging.error("Aborting: failed to fetch or parse API data.") sys.exit(1) + # Empty array → log & exit zero (no file change) if not new: - logging.error("Aborting: API returned an empty list.") - sys.exit(1) + logging.warning("API returned empty list; skipping write.") + sys.exit(0) + # Identical to existing → nothing to do if new == existing: - logging.info("No changes detected; skipping write.") - return + logging.info("Up-to-date; skipping write.") + sys.exit(0) + # Otherwise actually overwrite save_currencies(new, SAVE_PATH) + logging.info("✅ Currency file updated.") + if __name__ == "__main__": main()