mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-18 19:16:22 +00:00
* refactor 1: new typer based cli and browseros cli module * refactor 2: fixes to context.py * refactor 3: common/ and notify * new sign and package module * update .gitignore * refactor 5: dev.py and modules for each * refactor 6: clean-up old files * refactor 7: organise modules fruther * refactor 8: renaming nxtscape to browseros * refactor 9: dev.py remove cli load * fix: pyproject.toml * fix: typer pretty exception disable * refactor 10: cli/build.py set to primary * refactor 10: cli/build.py set to primary, move OS detection * refactor: context split, env and module dataclass * reactor: clean and git moved ot new module type * refactor: compile and configure * reactor: sign and package module update * refactor: new build.py cli * 'refactor: remove reducant OS checks * refactor: rename BuildContext to Context * refactor: rename BuildModule to CommandModule * refactor: dev.py to use the new modules * build.py: improve help output * remove old patching way * clean-up: remove old build.py stuff * refactor: move to proper yaml parsing * clean-up: remove legacy args gating * fix: patches issues * fix: clean-up build.py and ars resolver * minor: gitignore * fix: patches.py issue * support universal build * fix: ENV variable and YAMLs * fix: move compile to folder to avoid compflics * fixes: more env fixes * fix: build_type override in CLI fix * fix: universal clean all archs before starting * fix: universal build type constants * fix: linter, extract options * fix: linter * fix: remove chromium_src as a not a conflicting flag * fix: support chromium_src from cli in config mode * fix: notify with better messages * feat: new apply patch with --reset-to feature * feat: refactor apply and extract into separate sub modules * 142 patches working (#211) * updates to build.py apply/patch * removed all old patches * 142 build update * fix: get updated patches from main to 142 * fix: correct patches dir * fix: import path * add pyright * fix: setup pyright * fix: new updated patches from 137 rebased on 142 * feat: new extract_patch command * fix: add mising side_panel build patch * fix: extension uninstall for browseros * fix: prefs fix * fix: ota extension updater patch fix * fix: llm hub and chat * feat: unvisersal module also package individual archs * fix: add browseros-server binaries * fix: attach color for notify * fix: attachment for slack * fix: update chromium version to 142.0.7444.175 * feat: add new icons needed * fix: disable settings in menu * fix: uv add build-backend * minor: chromium version bump * clean-up: removed old files of extnesion and sidepanel * fix: product logo generate and assets.car and appicon.icns * feat: few chromium UI fixes * fix: update features.yaml * fix: features.yaml path in context * refactor: rename to get_patches_dir() * feat: show browserOS version in about page * fix: copy browseros_version on the build time and rename other to offset * bump offset * fix: update features.yaml * feat: load env from .env files too * fix: enable split view * clean-up: removed old prefs * fix: minor import issue * fix: linux flag update
165 lines
4.7 KiB
Python
Generated
165 lines
4.7 KiB
Python
Generated
#!/usr/bin/env python3
|
|
"""Notification system for BrowserOS build pipeline"""
|
|
|
|
import os
|
|
import threading
|
|
from typing import Optional, Dict, Any
|
|
|
|
# Slack attachment colors
|
|
COLOR_BLUE = "#2196F3"
|
|
COLOR_GREEN = "#4CAF50"
|
|
COLOR_RED = "#F44336"
|
|
|
|
# Build context (set once at pipeline start)
|
|
_build_context: Dict[str, str] = {}
|
|
|
|
|
|
def set_build_context(os_name: str, arch: str) -> None:
|
|
"""Set build context for all notifications"""
|
|
_build_context["os"] = os_name
|
|
_build_context["arch"] = arch
|
|
|
|
|
|
def _get_context_prefix() -> str:
|
|
"""Get [arch] prefix if context is set"""
|
|
if "arch" in _build_context:
|
|
return f"[{_build_context['arch']}] "
|
|
return ""
|
|
|
|
|
|
def _get_context_footer() -> str:
|
|
"""Get OS footer if context is set"""
|
|
if "os" in _build_context:
|
|
return f"BrowserOS Build System - {_build_context['os']}"
|
|
return "BrowserOS Build System"
|
|
|
|
|
|
class Notifier:
|
|
"""Fire-and-forget notification system"""
|
|
|
|
def __init__(self):
|
|
self.slack_webhook_url = os.environ.get("SLACK_WEBHOOK_URL")
|
|
self.enabled = bool(self.slack_webhook_url)
|
|
|
|
def notify(self, event: str, message: str, details: Optional[Dict[str, Any]] = None, color: str = "#36a64f") -> None:
|
|
"""Send notification asynchronously (fire-and-forget)"""
|
|
if not self.enabled:
|
|
return
|
|
|
|
# Fire and forget - run in background thread
|
|
thread = threading.Thread(
|
|
target=self._send_notification,
|
|
args=(event, message, details, color),
|
|
daemon=True
|
|
)
|
|
thread.start()
|
|
|
|
def _send_notification(self, event: str, message: str, details: Optional[Dict[str, Any]], color: str) -> None:
|
|
"""Internal method to send notification (runs in background thread)"""
|
|
try:
|
|
import requests
|
|
|
|
# Build footer text
|
|
footer = f"🍎 {_get_context_footer()}" if _build_context.get("os") == "macOS" \
|
|
else f"🪟 {_get_context_footer()}" if _build_context.get("os") == "Windows" \
|
|
else f"🐧 {_get_context_footer()}" if _build_context.get("os") == "Linux" \
|
|
else _get_context_footer()
|
|
|
|
# Use legacy attachment format for colored sidebar
|
|
attachment = {
|
|
"color": color,
|
|
"mrkdwn_in": ["text", "fields"],
|
|
"text": f"*{event}*\n{message}",
|
|
"footer": footer
|
|
}
|
|
|
|
if details:
|
|
attachment["fields"] = [
|
|
{"title": key, "value": str(value), "short": True}
|
|
for key, value in details.items()
|
|
]
|
|
|
|
payload = {"attachments": [attachment]}
|
|
|
|
requests.post(
|
|
self.slack_webhook_url,
|
|
json=payload,
|
|
timeout=5 # Quick timeout for fire-and-forget
|
|
)
|
|
|
|
except ImportError:
|
|
pass
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
# Global notifier instance
|
|
_notifier = None
|
|
|
|
|
|
def get_notifier() -> Notifier:
|
|
"""Get global notifier instance"""
|
|
global _notifier
|
|
if _notifier is None:
|
|
_notifier = Notifier()
|
|
return _notifier
|
|
|
|
|
|
def notify_pipeline_start(pipeline_name: str, modules: list) -> None:
|
|
"""Notify that pipeline has started"""
|
|
notifier = get_notifier()
|
|
notifier.notify(
|
|
"🚀 Pipeline Started",
|
|
"Build pipeline started",
|
|
{"Modules": ", ".join(modules)},
|
|
color=COLOR_BLUE
|
|
)
|
|
|
|
|
|
def notify_pipeline_end(pipeline_name: str, duration: float) -> None:
|
|
"""Notify that pipeline completed successfully"""
|
|
notifier = get_notifier()
|
|
mins = int(duration / 60)
|
|
secs = int(duration % 60)
|
|
notifier.notify(
|
|
"🏁 Pipeline Completed",
|
|
"Build pipeline completed successfully",
|
|
{"Duration": f"{mins}m {secs}s"},
|
|
color=COLOR_GREEN
|
|
)
|
|
|
|
|
|
def notify_pipeline_error(pipeline_name: str, error: str) -> None:
|
|
"""Notify that pipeline failed with error"""
|
|
notifier = get_notifier()
|
|
notifier.notify(
|
|
"❌ Pipeline Failed",
|
|
"Build pipeline failed",
|
|
{"Error": error},
|
|
color=COLOR_RED
|
|
)
|
|
|
|
|
|
def notify_module_start(module_name: str) -> None:
|
|
"""Notify that a module started executing"""
|
|
notifier = get_notifier()
|
|
prefix = _get_context_prefix()
|
|
notifier.notify(
|
|
"▶️ Module Started",
|
|
f"{prefix}Module '{module_name}' started",
|
|
None,
|
|
color=COLOR_BLUE
|
|
)
|
|
|
|
|
|
def notify_module_completion(module_name: str, duration: float) -> None:
|
|
"""Notify that a module completed successfully"""
|
|
notifier = get_notifier()
|
|
prefix = _get_context_prefix()
|
|
notifier.notify(
|
|
"✅ Module Completed",
|
|
f"{prefix}Module '{module_name}' completed",
|
|
{"Duration": f"{duration:.1f}s"},
|
|
color=COLOR_GREEN
|
|
)
|