#!/usr/bin/env python3 """ Local development script for building the Fusion gateway. This script is used for local development only. In CI/CD, subgraphs are built separately and the gateway is composed from pre-built .fsp artifacts. Usage: python build_gateway.py Requirements: - .NET 8.0 SDK - HotChocolate Fusion CLI (dotnet tool install -g HotChocolate.Fusion.CommandLine) """ import subprocess import sys import os from pathlib import Path def run(cmd, cwd=None): """Run a command and exit on failure.""" print(f"> {' '.join(cmd)}") result = subprocess.run(cmd, cwd=cwd) if result.returncode != 0: print(f"ERROR: command failed in {cwd or os.getcwd()}") sys.exit(result.returncode) def load_skip_list(skip_file: Path): if not skip_file.exists(): print(f"WARNING: gateway_skip.txt not found at {skip_file}") return set() lines = skip_file.read_text().splitlines() skip = {line.strip() for line in lines if line.strip() and not line.strip().startswith("#")} print("Skip list:", ", ".join(skip) if skip else "(none)") return skip # ---------------------------------------- # Setup paths # ---------------------------------------- script_dir = Path(__file__).parent.resolve() services_dir = (script_dir / "..").resolve() api_dir = services_dir / "FictionArchive.API" print(f"Script dir: {script_dir}") print(f"Services dir: {services_dir}") skip_file = script_dir / "gateway_skip.txt" skip_list = load_skip_list(skip_file) # ---------------------------------------- # Find services # ---------------------------------------- print("\n----------------------------------------") print(" Finding GraphQL services...") print("----------------------------------------") service_dirs = [ d for d in services_dir.glob("FictionArchive.Service.*") if d.is_dir() and (d / "subgraph-config.json").exists() ] selected_services = [] for d in service_dirs: name = d.name if name in skip_list: print(f"Skipping: {name}") else: print(f"Found: {name}") selected_services.append(d) if not selected_services: print("No services to process. Exiting.") sys.exit(0) # ---------------------------------------- # Export + pack # ---------------------------------------- print("\n----------------------------------------") print(" Exporting schemas & packing subgraphs...") print("----------------------------------------") for svc in selected_services: name = svc.name print(f"\nProcessing {name}") # Build once run(["dotnet", "build", "-c", "Release"], cwd=svc) # Export schema run([ "dotnet", "run", "--no-build", "--no-launch-profile", "--", "schema", "export", "--output", "schema.graphql" ], cwd=svc) # Pack subgraph run(["fusion", "subgraph", "pack"], cwd=svc) # ---------------------------------------- # Compose gateway # ---------------------------------------- print("\n----------------------------------------") print(" Running fusion compose...") print("----------------------------------------") if not api_dir.exists(): print(f"ERROR: FictionArchive.API not found at {api_dir}") sys.exit(1) gateway_file = api_dir / "gateway.fgp" if gateway_file.exists(): gateway_file.unlink() for svc in selected_services: name = svc.name print(f"Composing: {name}") run([ "fusion", "compose", "-p", "gateway.fgp", "-s", f"..{os.sep}{name}" ], cwd=api_dir) print("\n----------------------------------------") print(" Fusion build complete!") print("----------------------------------------")