Files
gti d21a9d1140 Add 'fiscal/' from commit '102ba84500dbd9655a0471288c3e278652593ca9'
git-subtree-dir: fiscal
git-subtree-mainline: d95165fc8f
git-subtree-split: 102ba84500
2026-09-29 14:43:23 -03:00

62 lines
3.5 KiB
Python

"""Write release/RELEASE_MANIFEST.json: one coherent record of what RC1 is made of (no secrets).
python scripts/release_manifest.py <AGENT_TOKEN> [HUB_URL]
Registers together: release version, agent/hub versions, fiscal engine + decision versions, engine module versions, ACTIVE dataset versions
(kind, provider, sha256, record_count) read from the running Hub, alembic head (from the migration files) and the applied revision.
"""
import json
import os
import re
import subprocess
import sys
import urllib.request
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
def get(url, token):
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"})
with urllib.request.urlopen(req, timeout=30) as r:
return json.load(r)
def main():
token = sys.argv[1]
hub = sys.argv[2] if len(sys.argv) > 2 else "http://localhost:8000"
from central.app.classification import DECISION_VERSION, ENGINE_VERSION
from central.app.fiscal_decision import DECISION_ENGINE_VERSION
from central.app.icms_context import ICMS_CONTEXT_ENGINE_VERSION
from central.app.product_defaults import PRODUCT_DEFAULTS_ENGINE_VERSION
version = (ROOT / "release" / "VERSION").read_text(encoding="utf-8").strip()
# Real revision ids (e.g. "0020_not_null_timestamps"), not file-name prefixes:
# from 0015 on the id is longer than the 4-digit prefix.
from alembic.config import Config
from alembic.script import ScriptDirectory
alembic_cfg = Config(str(ROOT / "central" / "alembic.ini"))
alembic_cfg.set_main_option("script_location", str(ROOT / "central" / "alembic"))
script = ScriptDirectory.from_config(alembic_cfg)
head, revision_count = script.get_current_head(), len(list(script.walk_revisions()))
container = os.getenv("HUB_CONTAINER", "projeto-fiscal-hub-1")
try:
current = subprocess.run(["docker", "exec", container, "sh", "-c", "cd /app && alembic -c central/alembic.ini current"], capture_output=True, text=True, timeout=60).stdout
applied = re.findall(r"^(\d{4}\S*)", current, re.M)[-1:] or ["unknown"]
except Exception: # noqa: BLE001
applied = ["unknown"]
datasets = sorted(({"kind": d["kind"], "sha256": d["sha256"][:16], "record_count": d["record_count"]} for d in get(f"{hub}/v1/datasets/status", token) if d["status"] == "ACTIVE"), key=lambda x: x["kind"])
manifest = {"artifact": "RELEASE_MANIFEST", "GTI_FISCAL_VERSION": version, "generated_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
"hub": get(f"{hub}/version", token), "agent_version": version,
"fiscal_engine": {"ENGINE_VERSION": ENGINE_VERSION, "DECISION_VERSION": DECISION_VERSION, "DECISION_ENGINE_VERSION": DECISION_ENGINE_VERSION,
"PRODUCT_DEFAULTS_ENGINE_VERSION": PRODUCT_DEFAULTS_ENGINE_VERSION, "ICMS_CONTEXT_ENGINE_VERSION": ICMS_CONTEXT_ENGINE_VERSION},
"migrations": {"alembic_head_in_repo": head, "applied_revision": applied[0], "applied_revision_source": f"container {container}", "count": revision_count},
"datasets_active": datasets, "note": "A release bump does not change fiscal semantics; engine/decision versions are versioned independently."}
(ROOT / "release" / "RELEASE_MANIFEST.json").write_text(json.dumps(manifest, indent=1), encoding="utf-8")
print(json.dumps({"version": version, "engine": ENGINE_VERSION, "migrations": manifest["migrations"], "datasets": len(datasets)}))
if __name__ == "__main__":
main()