feat(gas-deploy): auto-update gas_lib timestamp and enforce clasp deploy versioning
This commit is contained in:
@@ -15,5 +15,5 @@
|
|||||||
"keep package scripts within release envelope"
|
"keep package scripts within release envelope"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"source_zip_sha256": "cab190780926902cc59c306f9889b38ae801a2dab2e83a9818081ec597976653"
|
"source_zip_sha256": "62840230a4e2c3ef94571ffe40797dd7d84679c98ad79ac6d59f67b11d1afbe7"
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// gas_lib.gs - Common utilities & static features
|
// gas_lib.gs - Common utilities & static features
|
||||||
// Last Updated: 2026-06-13 18:48:40 KST
|
// Last Updated: 2026-06-14 13:01:11 KST
|
||||||
// Math/KRX utils, sheet I/O, sector flow, Web API, static runners
|
// Math/KRX utils, sheet I/O, sector flow, Web API, static runners
|
||||||
// GAS global scope: functions in gas_data_feed.gs / gas_data_collect.gs callable directly
|
// GAS global scope: functions in gas_data_feed.gs / gas_data_collect.gs callable directly
|
||||||
//
|
//
|
||||||
|
|||||||
+54
-1
@@ -54,9 +54,17 @@ BUNDLE_MAP: dict[str, list[str]] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SCRIPT_ID = "1xfeBAeeknmnBtSvrIqWXO_2hc3ByeriLUOSuOOB4YxLLHhN3zdnL7tVh"
|
SCRIPT_ID = "1xfeBAeeknmnBtSvrIqWXO_2hc3ByeriLUOSuOOB4YxLLHhN3zdnL7tVh"
|
||||||
|
DEPLOYMENT_ID = "AKfycbzq1XM53XafyCNYurnF9TAQHT3FHBDsBd36rCbCoWSmJD3SaZ1BHCPDYZYhclG9qD5Y"
|
||||||
|
|
||||||
|
|
||||||
|
def get_now_kst() -> str:
|
||||||
|
from datetime import datetime, timezone, timedelta
|
||||||
|
kst = timezone(timedelta(hours=9))
|
||||||
|
return datetime.now(kst).strftime("%Y-%m-%d %H:%M:%S KST")
|
||||||
|
|
||||||
|
|
||||||
def build_deploy(dry_run: bool = False) -> bool:
|
def build_deploy(dry_run: bool = False) -> bool:
|
||||||
|
import re
|
||||||
print("[deploy_gas] src_parts=" + str(SRC_PARTS))
|
print("[deploy_gas] src_parts=" + str(SRC_PARTS))
|
||||||
print("[deploy_gas] src_gas= " + str(SRC_GAS))
|
print("[deploy_gas] src_gas= " + str(SRC_GAS))
|
||||||
print("[deploy_gas] dst= " + str(DEPLOY_DIR))
|
print("[deploy_gas] dst= " + str(DEPLOY_DIR))
|
||||||
@@ -65,6 +73,7 @@ def build_deploy(dry_run: bool = False) -> bool:
|
|||||||
shutil.rmtree(DEPLOY_DIR)
|
shutil.rmtree(DEPLOY_DIR)
|
||||||
DEPLOY_DIR.mkdir(parents=True, exist_ok=True)
|
DEPLOY_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
now_kst = get_now_kst()
|
||||||
ok = True
|
ok = True
|
||||||
for dst_name, src_files in BUNDLE_MAP.items():
|
for dst_name, src_files in BUNDLE_MAP.items():
|
||||||
dst_path = DEPLOY_DIR / dst_name
|
dst_path = DEPLOY_DIR / dst_name
|
||||||
@@ -75,7 +84,24 @@ def build_deploy(dry_run: bool = False) -> bool:
|
|||||||
print(" WARN: " + sf + " not found")
|
print(" WARN: " + sf + " not found")
|
||||||
ok = False
|
ok = False
|
||||||
continue
|
continue
|
||||||
parts.append(src_path.read_text(encoding="utf-8"))
|
|
||||||
|
# Update Last Updated timestamp for gas_lib.gs in place before copying
|
||||||
|
if sf == "gas_lib.gs" and not dry_run:
|
||||||
|
orig_content = src_path.read_text(encoding="utf-8")
|
||||||
|
updated_orig = re.sub(
|
||||||
|
r"//\s*Last\s+Updated:\s*\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+KST",
|
||||||
|
f"// Last Updated: {now_kst}",
|
||||||
|
orig_content
|
||||||
|
)
|
||||||
|
if updated_orig != orig_content:
|
||||||
|
src_path.write_text(updated_orig, encoding="utf-8")
|
||||||
|
print(f" [gas_lib.gs] Updated source file 'Last Updated' timestamp to: {now_kst}")
|
||||||
|
parts.append(updated_orig)
|
||||||
|
else:
|
||||||
|
parts.append(orig_content)
|
||||||
|
else:
|
||||||
|
parts.append(src_path.read_text(encoding="utf-8"))
|
||||||
|
|
||||||
if not parts:
|
if not parts:
|
||||||
continue
|
continue
|
||||||
content = "\n".join(parts)
|
content = "\n".join(parts)
|
||||||
@@ -117,6 +143,29 @@ def clasp_push() -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def clasp_deploy() -> bool:
|
||||||
|
print(f"[deploy_gas] clasp deploy -i {DEPLOYMENT_ID} ...")
|
||||||
|
now_kst = get_now_kst()
|
||||||
|
desc = f"Auto-deployed on {now_kst}"
|
||||||
|
res = subprocess.run(
|
||||||
|
["npx", "@google/clasp", "deploy", "-i", DEPLOYMENT_ID, "-d", desc],
|
||||||
|
cwd=str(ROOT),
|
||||||
|
shell=True,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
encoding="utf-8",
|
||||||
|
errors="replace",
|
||||||
|
)
|
||||||
|
print(res.stdout)
|
||||||
|
if res.stderr:
|
||||||
|
print("STDERR: " + res.stderr[:500])
|
||||||
|
if res.returncode == 0:
|
||||||
|
print("[deploy_gas] clasp deploy OK")
|
||||||
|
return True
|
||||||
|
print("[deploy_gas] clasp deploy FAILED rc=" + str(res.returncode))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
parser = argparse.ArgumentParser(description="GAS auto-deploy")
|
parser = argparse.ArgumentParser(description="GAS auto-deploy")
|
||||||
parser.add_argument("--dry-run", action="store_true", help="List files without writing")
|
parser.add_argument("--dry-run", action="store_true", help="List files without writing")
|
||||||
@@ -135,8 +184,12 @@ def main() -> None:
|
|||||||
if not clasp_push():
|
if not clasp_push():
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
if not clasp_deploy():
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
print("[deploy_gas] Done. To run_all: python tools/automate_routine.py")
|
print("[deploy_gas] Done. To run_all: python tools/automate_routine.py")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user