#!/usr/bin/env lmscript # scripts/deploy-site.lms # # Publish all static website files in site/ to the S3 origin bucket for lmscript.io # using lmctl-ai/lmaws: # - Live/Sim mode (`live`): uses cloud.s3_bucket_attach + cloud.s3_put_file (SHA-256 # checksums, Content-Type, Cache-Control) + s3_head_object + s3_list_objects + s3_ledger_summary. # - Offline preview mode (`preview`, default): uses aws.demo().example_run().bucket("site") # and run.put(b, key, file_read(...)) to verify every file in site/ offline. # # Usage: # lmscript --check scripts/deploy-site.lms # lmscript scripts/deploy-site.lms # AWS_PROFILE=lmaws lmscript scripts/deploy-site.lms live const SITE_DIR = "site"; const REGION = "us-east-1"; const RUN_ID = "a1b2c3d4"; const BUCKET = "lmaws-site-a1b2c3d4"; const HTML_KEYS = [ "index.html", "404.html", "about.html", "robots.txt", "sitemap.xml", "assets/style.css", "assets/app.js", "assets/icon.svg", "assets/architecture.svg", "assets/dslb-pipeline.svg", "lmscript/index.html", "lmscript/guide.html", "lmscript/stdlib.html", "lmscript/examples.html", "lmscript/agentic.html", "lmscript/comparisons.html", "lmscript/cheatsheet.html", "lmcode/index.html", "lmcode/tutorial.html", "lmcode/language.html", "lmcode/hosts.html", "lmcode/stdlib.html", "lmcode/ecosystem.html", "examples/index.html", "examples/lmscript/hello.lms", "examples/lmscript/python-strings.lms", "examples/lmscript/regex-tokenizer.lms", "examples/lmscript/functions.lms", "examples/lmscript/data-blocks.lms", "examples/lmscript/processes.lms", "examples/lmscript/reverse-template.lms", "examples/lmscript/sqlite-demo.lms", "examples/lmcode/host.schema.json", "examples/lmcode/literals-and-std.lms", "examples/lmcode/shop-rules.lms", "examples/lmcode/lmaws-zones-demo.lms", "examples/lmcode/setup-lmscript-io.lms", "examples/lmcode/deploy-site.lms", "examples/lmcode/test-lmwebtest.lms" ]; mode = ARGV.get(0, "preview"); is_live = (mode == "live" || mode == "--live" || env("LMAWS_LIVE", "0") == "1"); println("================================================================"); println(" lmscript.io — S3 Static Website Publisher (lmaws)"); println("================================================================"); println(" Mode : " + (is_live ? f"LIVE AWS ({REGION})" : "preview (aws.demo() offline)")); println(" Target S3 : s3://" + BUCKET); println(" Source Dir : " + SITE_DIR); println(" Object Keys : " + str(HTML_KEYS.len())); println("----------------------------------------------------------------"); live_pub_prog = _lmcode_ cli="lmaws" install="github:lmctl-ai/lmaws@v0.1.34"; fn content_type(k: string) -> string { let ct = "text/plain; charset=utf-8"; if (str_ends_with(k, ".html")) { ct = "text/html; charset=utf-8"; } else if (str_ends_with(k, ".css")) { ct = "text/css; charset=utf-8"; } else if (str_ends_with(k, ".js")) { ct = "application/javascript; charset=utf-8"; } else if (str_ends_with(k, ".svg")) { ct = "image/svg+xml"; } else if (str_ends_with(k, ".json")) { ct = "application/json; charset=utf-8"; } else if (str_ends_with(k, ".xml")) { ct = "application/xml; charset=utf-8"; } return ct; } fn cache_control(k: string) -> string { let cc = "public, max-age=600"; if (str_starts_with(k, "assets/")) { cc = "public, max-age=3600, stale-while-revalidate=86400"; } else if (str_ends_with(k, ".html")) { cc = "public, max-age=300, must-revalidate"; } return cc; } let cloud = aws.region(${REGION}); let keys = ${HTML_KEYS}; let attach = cloud.s3_bucket_attach(${BUCKET}, ${RUN_ID}); let count = keys.len(); for (k in keys) { let ct = content_type(k); let cc = cache_control(k); let opts = "{\"content_type\":\"" + ct + "\",\"cache_control\":\"" + cc + "\",\"checksum_algorithm\":\"SHA256\"}"; cloud.s3_put_file(${BUCKET}, k, "site/" + k, opts); } let head_root = cloud.s3_head_object(${BUCKET}, "index.html"); let listed = cloud.s3_list_objects(${BUCKET}, "", 200); let ledger = aws.s3_ledger_summary(${RUN_ID}); lmcode_return_put("attached", json_parse(attach)); lmcode_return_put("uploaded_count", count); lmcode_return_put("head_index", json_parse(head_root)); lmcode_return_put("listed", json_parse(listed.json())); lmcode_return_put("ledger", json_parse(ledger)); end _lmcode_ demo_pub_prog = _lmcode_ cli="lmaws" install="github:lmctl-ai/lmaws@v0.1.34"; let cloud = aws.demo(); let keys = ${HTML_KEYS}; let run = cloud.example_run(); let b = run.bucket("site"); let bytes = 0; for (k in keys) { let body = file_read("site/" + k); bytes = bytes + str_len(body); run.put(b, k, body); } let est_cost = run.estimated_cost(); run.cleanup(); lmcode_return_put("bucket", json_parse(b.json())); lmcode_return_put("uploaded_count", keys.len()); lmcode_return_put("total_bytes", bytes); lmcode_return_put("estimated_cost", est_cost); end _lmcode_ res = is_live ? run_lmcode(live_pub_prog) : run_lmcode(demo_pub_prog); require(res.ok, "S3 static website publish failed"); println(" Uploaded Objects : " + str(res.result.uploaded_count)); if (res.result.has("total_bytes")) { println(" Total Site Bytes : " + str(res.result.total_bytes) + " bytes"); } if (res.result.has("head_index")) { println(" index.html ETag : " + res.result.head_index.get("etag", "")); } mkdir(".lmweblab-local"); deploy_receipt = f".lmweblab-local/deploy-receipt-{RUN_ID}.json"; write_file(deploy_receipt, json_stringify(res.result, 2) + "\n"); println(" Deploy Receipt : " + deploy_receipt);