diff --git a/benchmate/api/actions/create_site.py b/benchmate/api/actions/create_site.py
index f6dfdc2..e3f3ccf 100644
--- a/benchmate/api/actions/create_site.py
+++ b/benchmate/api/actions/create_site.py
@@ -30,7 +30,9 @@ def update_log_status(docname, new_text=None, status=None):
frappe.log_error(f"Error updating BM Site Creation Logs: {e}", "BenchMate SiteCreationLogs")
-def create_site_background(bench_path: str, site_name: str, sudo_password: str, mysql_root_password: str):
+def create_site_background(
+ bench_name: str, bench_path: str, site_name: str, sudo_password: str, mysql_root_password: str
+):
"""
Background task to create a new Frappe site inside a given bench.
Captures real-time logs into BM Site Creation Logs doctype,
@@ -104,13 +106,31 @@ def create_site_background(bench_path: str, site_name: str, sudo_password: str,
# ? Update status based on exit code
if proc.returncode == 0:
update_log_status(log_name, status="Success")
+ create_bm_site(bench_name=bench_name, bench_path=bench_path, site_name=site_name)
+
else:
update_log_status(log_name, status="Error")
except Exception as e:
+ frappe.msgprint(
+ msg=f"Error While Creating Site {site_name} in bench {bench_name}",
+ title="Site Creation Error",
+ realtime=True,
+ alert=True,
+ indicator="red",
+ )
frappe.log_error(f"Error tailing bench new-site log: {e}", "BenchMate SiteCreationLogs")
update_log_status(log_name, status="Error")
+ else:
+ frappe.msgprint(
+ msg=f"Site {site_name} created successfully. in bench {bench_name}",
+ title="Site Creation Success",
+ realtime=True,
+ alert=True,
+ indicator="green",
+ )
+
finally:
# ? Always clean up the temporary log file
try:
@@ -123,8 +143,61 @@ def create_site_background(bench_path: str, site_name: str, sudo_password: str,
)
+def create_bm_site(bench_name: str, bench_path: str, site_name: str):
+ """
+ Create a new BM Site record in the system.
+ Links the site to its bench, sets its status as Active,
+ adds metadata (path, sync time), and attaches default apps.
+ """
+
+ # ? Initialize a new BM Site document
+ bm_site_doc = frappe.new_doc("BM Site")
+
+ # ? Populate the BM Site document with essential details
+ bm_site_doc.update(
+ {
+ "bench_name": bench_name,
+ "bench_path": bench_path,
+ "site_name": site_name,
+ "status": "Active",
+ "last_synced_on": frappe.utils.now_datetime(),
+ "path": os.path.join(bench_path, "sites", site_name),
+ }
+ )
+
+ # ? Fetch default frappe app metadata from BM Installed Apps for this bench
+ bm_bench_default_apps = (
+ frappe.db.get_value(
+ "BM Installed Apps",
+ {
+ "parent": bench_name,
+ "app_name": "frappe",
+ },
+ [
+ "app_name",
+ "app_title",
+ "branch",
+ "version",
+ "link",
+ "commit",
+ ],
+ as_dict=1,
+ )
+ or {}
+ )
+
+ # ? Attach frappe app metadata into the site's installed apps child table
+ bm_site_doc.append("installed_apps", bm_bench_default_apps)
+
+ # ? Save the BM Site record into the database
+ bm_site_doc.insert()
+
+ # ? Commit immediately to make sure the new site is persisted
+ frappe.db.commit()
+
+
@frappe.whitelist()
-def execute(bench_path: str, site_name: str):
+def execute(bench_name: str, bench_path: str, site_name: str):
"""
? Public API method (whitelisted) to enqueue site creation.
? Validates input and enqueues the background site creation task.
@@ -149,6 +222,7 @@ def execute(bench_path: str, site_name: str):
create_site_background,
queue="long",
timeout=3600,
+ bench_name=bench_name,
bench_path=bench_path,
site_name=site_name,
sudo_password=sudo_password,
diff --git a/benchmate/benchmate/doctype/bm_bench/bm_bench.js b/benchmate/benchmate/doctype/bm_bench/bm_bench.js
index 22a74f3..d5cf6ef 100644
--- a/benchmate/benchmate/doctype/bm_bench/bm_bench.js
+++ b/benchmate/benchmate/doctype/bm_bench/bm_bench.js
@@ -55,6 +55,7 @@ function createSite(frm) {
frappe.call({
method: "benchmate.api.actions.create_site.execute",
args: {
+ bench_name: frm.doc.name,
bench_path: frm.doc.path,
site_name: values.site_name,
},
diff --git a/benchmate/benchmate/workspace/benchmate/benchmate.json b/benchmate/benchmate/workspace/benchmate/benchmate.json
index 26cef88..ea97eca 100644
--- a/benchmate/benchmate/workspace/benchmate/benchmate.json
+++ b/benchmate/benchmate/workspace/benchmate/benchmate.json
@@ -1,7 +1,7 @@
{
"app": "benchmate",
"charts": [],
- "content": "[{\"id\":\"E4TboPQAiW\",\"type\":\"header\",\"data\":{\"text\":\"BenchMate\",\"col\":12}},{\"id\":\"pckRgVGLCJ\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Bench\",\"col\":3}},{\"id\":\"uIKLe2weO2\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Site\",\"col\":3}},{\"id\":\"1zPvETmYcy\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM App\",\"col\":3}},{\"id\":\"OdX7vGpNVa\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Sync Log\",\"col\":3}},{\"id\":\"Zlbft996Gt\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Settings\",\"col\":3}}]",
+ "content": "[{\"id\":\"E4TboPQAiW\",\"type\":\"header\",\"data\":{\"text\":\"BenchMate\",\"col\":12}},{\"id\":\"pckRgVGLCJ\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Bench\",\"col\":3}},{\"id\":\"uIKLe2weO2\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Site\",\"col\":3}},{\"id\":\"1zPvETmYcy\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM App\",\"col\":3}},{\"id\":\"OdX7vGpNVa\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Sync Log\",\"col\":3}},{\"id\":\"CZYPa4MOMK\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Bm Site Creation Logs\",\"col\":3}},{\"id\":\"Zlbft996Gt\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"BM Settings\",\"col\":3}}]",
"creation": "2025-08-18 03:30:43.609066",
"custom_blocks": [],
"docstatus": 0,
@@ -15,7 +15,7 @@
"label": "BenchMate",
"link_type": "DocType",
"links": [],
- "modified": "2025-08-18 03:34:53.200507",
+ "modified": "2025-09-07 21:22:03.176848",
"modified_by": "Administrator",
"module": "BenchMate",
"name": "BenchMate",
@@ -27,6 +27,14 @@
"roles": [],
"sequence_id": 23.0,
"shortcuts": [
+ {
+ "color": "Grey",
+ "doc_view": "List",
+ "label": "Bm Site Creation Logs",
+ "link_to": "BM Site Creation Logs",
+ "stats_filter": "[]",
+ "type": "DocType"
+ },
{
"color": "Grey",
"doc_view": "List",