xbp 10.5.0

XBP is a zero-config build pack that can also interact with proxies, kafka, sockets, synthetic monitors.
Documentation
import re
from log_to_server import XbpLog
import time
import asyncio


async def parse_nextjs_logs(line, deployment_data):
    """
    Matches a line against predefined regex patterns and logs to Supabase if a match is found.
    Returns True if the deployment process is fully completed, otherwise False.

    Args:
        line (str): The line to be matched.
        deployment_data (dict): Deployment metadata to be included in the log.
    """
    # Define regex patterns to match
    patterns = {
        r"Redeploying .*":
        "Redeploying project",
        r"Resetting local changes for (.+) \.\.\.":
        lambda match: f"Resetting the git commit tree on {match.group(1)}",
        r"Pulling latest changes for .*":
        "Pulling new git changes onto local repository",
        r"Already up to date\.":
        "Successfully synced git to local repository",
        r"Installing dependencies for .*":
        "Installing dependencies for the project",
        r"Done in (\d+\.\d+)s":
        lambda match:

        f"Successfully installed all dependencies in {match.group(1)} seconds",
        r"Building .*":
        "Initializing build of project",
        r"Generating static pages \((\d+)/(\d+)\)":
        lambda match:

        f"Generating static pages: {match.group(1)}/{match.group(2)} completed",
        r"Creating an optimized production build .*":
        "Creating an optimized production build",
        r"Finalizing page optimization \.\.\.":
        "Finalizing the build process",
        r"Collecting build traces \.\.\.":
        "Collecting build traces and finalizing deployment",
        r"Received GET request to generate thumbnail.*":
        "Processing GET request to generate thumbnail",
        r"sudo: .*":
        "Executing command with elevated privileges",
        r"▲ Next\.js (\d+\.\d+\.\d+)":
        lambda match: f"Using Next.js version {match.group(1)}",
        r"HEAD is now at ([a-f0-9]+)":
        lambda match:

        f"Successfully reset the git commit tree to {match.group(1)}",
        r"\(Static\).*":
        "Build completed successfully. Deployment will follow next.",
        r"ƒ \(Dynamic\).*":
        "Build completed successfully. Deployment will follow next.",
        r"Stopping existing PM2 process for (.+) \.\.\.":
        lambda match:

        f"Replacing old build with the new build for {match.group(1)}",
        r"\[PM2\] Applying action stopProcessId on app \[(.+)\]\(ids: \[ (\d+) \]\)":
        lambda match:

        f"Successfully killed old build for {match.group(1)} (Process ID: {match.group(2)})",
        r"\[PM2\] \[(.+)\]\((\d+)\)":
        lambda match:

        f"Successfully deployed {match.group(1)} (Process ID: {match.group(2)})",
    }

    # Check if the line matches any of the patterns
    for pattern, message in patterns.items():
        match = re.search(pattern, line)
        if match:
            # Determine the log message
            log_message = message(match) if callable(message) else message

            # Extract Next.js version if matched
            runtime_version = match.group(
                1) if "▲ Next.js" in pattern else "14.2.23"

            # Prepare the log data
            log_data = {
                "time":
                int(time.time()),
                "request":
                None,
                "http_status":
                None,
                "method":
                None,
                "payload":
                None,
                "status":
                deployment_data.status,
                "message":
                log_message,
                "deployment_id":
                deployment_data.deployment_id,
                "commit_id":
                deployment_data.sha_short,
                "project_id":
                deployment_data.project_id,
                "action":
                "log_line_match",
                "host":
                "xylex.cloud",
                "user_agent":
                "xbp/nextjs",
                "content_type":
                None,
                "repository_url":
                f"https://github.com/{deployment_data.repository_owner}/{deployment_data.repository_name}",
                "error":
                False,
                "runtime_version":
                runtime_version,
                "runtime":
                "nodejs",
                "framework":
                "Next.js",
                "total_pages":
                int(match.group(2))
                if "Generating static pages" in pattern else None,
                "build_time":
                None,
                "time_start":
                None,
                "time_finish":
                None,
                "lint_time":
                None,
                "routes_sourcemap":
                None,
                "build_duration":
                None,
                "lint_duration":
                None,
                "routes_duration":
                None,
                "routes":
                None,
                "routes_count":
                None,
                "routes_time":
                None,
            }

            # Create an XbpLog instance and log to Supabase
            try:
                xbp_log = XbpLog(**log_data)
                XbpLog.add_xbp_log_to_supabase(xbp_log)
                print(f"Logged line to Supabase: {log_message}")
            except Exception as e:
                print(f"Failed to log line to Supabase: {str(e)}")

            # Wait 10 seconds before returning True if the pattern indicates full deployment
            if "Successfully deployed" in log_message:
                deployment_data.status = "success"
                import httpx

                async with httpx.AsyncClient() as client:
                    payload = {
                        "sha": deployment_data.sha,
                        "sha_short": deployment_data.sha_short,
                        "github_username": deployment_data.github_username,
                        "organization_name": deployment_data.organization_name,
                        "project_name": deployment_data.project_name,
                        "deployment_id": deployment_data.deployment_id,
                        "status": deployment_data.status,
                        "repository_name": deployment_data.repository_name,
                        "repository_owner": deployment_data.repository_owner,
                        "xbp_command": deployment_data.xbp_command,
                        "project_id": deployment_data.project_id,
                    }
                    response = await client.post(
                        "https://xbp.xylex.cloud/report-deployment-status",
                        json=payload)
                    print(
                        f"Report deployment status response: {response.status_code}, {response.text}"
                    )
                await asyncio.sleep(10)
                return True
            break

    # Return False if no pattern indicates full deployment
    return False