@delta-base/observability
Version:
Observability framework for delta-base applications
1 lines • 11.2 kB
Source Map (JSON)
{"version":3,"sources":["../../src/scripts/collect-build-info.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nfunction safeExec(command: string, fallback = ''): string {\n try {\n return execSync(command, { encoding: 'utf8', stdio: 'pipe' }).trim();\n } catch (error) {\n console.warn(\n `Warning: Failed to execute \"${command}\": ${error instanceof Error ? error.message : String(error)}`\n );\n return fallback;\n }\n}\n\nexport interface BuildInfoOptions {\n /** Path to the directory containing package.json (defaults to current working directory) */\n packageJsonDir?: string;\n /** Path to the output directory (defaults to src/) */\n outputDir?: string;\n /** Name of the output file (defaults to build-info.ts) */\n outputFileName?: string;\n /** Default service name if not found in package.json */\n defaultServiceName?: string;\n /** Whether to include git information */\n includeGitInfo?: boolean;\n /** Whether to include CI/CD information */\n includeCiInfo?: boolean;\n /** Additional custom build info fields */\n customFields?: Record<string, string | number | boolean>;\n}\n\nexport function collectBuildInfo(\n options: BuildInfoOptions = {}\n): Record<string, string | number | boolean> {\n const {\n packageJsonDir = process.cwd(),\n outputDir = 'src',\n outputFileName = 'build-info.ts',\n defaultServiceName = 'unknown-service',\n includeGitInfo = true,\n includeCiInfo = true,\n customFields = {},\n } = options;\n\n console.log('Collecting build information...');\n\n // Read package.json\n const packageJsonPath = resolve(packageJsonDir, 'package.json');\n let packageJson: any = {};\n if (existsSync(packageJsonPath)) {\n packageJson = require(packageJsonPath);\n } else {\n console.warn(`Warning: package.json not found at ${packageJsonPath}`);\n }\n\n const buildInfo: Record<string, string | number | boolean> = {\n 'service.name': packageJson.name || defaultServiceName,\n 'service.version': packageJson.version || '0.0.0',\n 'build.timestamp': new Date().toISOString(),\n ...customFields,\n };\n\n // Environment detection\n const environment =\n process.env.NODE_ENV ||\n process.env.CLOUDFLARE_ENVIRONMENT ||\n process.env.ENVIRONMENT ||\n 'development';\n\n buildInfo['service.environment'] = environment;\n\n // Git information\n if (includeGitInfo) {\n const gitHash = safeExec('git rev-parse HEAD', 'unknown');\n const gitShortHash = gitHash.substring(0, 7);\n const gitBranch = safeExec('git rev-parse --abbrev-ref HEAD', 'unknown');\n const gitMessage = safeExec('git log -1 --pretty=%s', 'unknown');\n const gitAuthor = safeExec('git log -1 --pretty=%an', 'unknown');\n const gitTimestamp = safeExec(\n 'git log -1 --pretty=%ai',\n new Date().toISOString()\n );\n const gitStatus = safeExec('git status --porcelain', '');\n\n Object.assign(buildInfo, {\n 'git.commit_hash': gitHash,\n 'git.commit_hash_short': gitShortHash,\n 'git.branch': gitBranch,\n 'git.commit_message': gitMessage,\n 'git.commit_author': gitAuthor,\n 'git.commit_timestamp': gitTimestamp,\n 'git.is_dirty': gitStatus.length > 0,\n });\n }\n\n // CI/CD information\n if (includeCiInfo) {\n const ciUser =\n process.env.GITHUB_ACTOR ||\n process.env.GITLAB_USER_LOGIN ||\n process.env.USER ||\n process.env.USERNAME ||\n 'unknown';\n\n const deploymentTrigger =\n process.env.GITHUB_EVENT_NAME ||\n process.env.CI_PIPELINE_SOURCE ||\n 'manual';\n\n Object.assign(buildInfo, {\n 'build.id': process.env.GITHUB_RUN_ID || Date.now().toString(),\n 'deployment.user': ciUser,\n 'deployment.trigger': deploymentTrigger,\n 'deployment.ci_build_id':\n process.env.GITHUB_RUN_ID || process.env.CI_JOB_ID,\n 'deployment.ci_build_url':\n process.env.GITHUB_SERVER_URL &&\n process.env.GITHUB_REPOSITORY &&\n process.env.GITHUB_RUN_ID\n ? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`\n : undefined,\n });\n\n // Repository URLs\n const repoUrl =\n process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY\n ? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`\n : undefined;\n\n const prNumber = process.env.GITHUB_EVENT_PULL_REQUEST_NUMBER;\n const prUrl =\n repoUrl && prNumber ? `${repoUrl}/pull/${prNumber}` : undefined;\n\n const compareUrl =\n repoUrl && includeGitInfo\n ? `${repoUrl}/compare/${buildInfo['git.commit_hash_short']}..HEAD`\n : undefined;\n\n if (repoUrl) buildInfo['git.repository_url'] = repoUrl;\n if (prUrl) buildInfo['git.pull_request_url'] = prUrl;\n if (compareUrl) buildInfo['git.compare_url'] = compareUrl;\n }\n\n // Write to TypeScript file\n const outputPath = resolve(outputDir, outputFileName);\n const content = `// Auto-generated build info - do not edit manually\n// Generated at: ${new Date().toISOString()}\n\nexport const BUILD_INFO = ${JSON.stringify(buildInfo, null, 2)} as const;\n\nexport type BuildInfo = typeof BUILD_INFO;\n`;\n\n writeFileSync(outputPath, content);\n\n console.log('Build info collected successfully:');\n console.log(\n ` Service: ${buildInfo['service.name']}@${buildInfo['service.version']}`\n );\n console.log(` Environment: ${buildInfo['service.environment']}`);\n if (includeGitInfo) {\n console.log(\n ` Git: ${buildInfo['git.branch']}@${buildInfo['git.commit_hash_short']}`\n );\n console.log(` Author: ${buildInfo['git.commit_author']}`);\n }\n if (includeCiInfo) {\n console.log(` Deployed by: ${buildInfo['deployment.user']}`);\n }\n\n return buildInfo;\n}\n\n// Command line interface\nif (require.main === module) {\n const args = process.argv.slice(2);\n const options: BuildInfoOptions = {};\n\n // Parse command line arguments\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n const nextArg = args[i + 1];\n\n switch (arg) {\n case '--package-json-dir':\n options.packageJsonDir = nextArg;\n i++; // Skip next argument\n break;\n case '--output-dir':\n options.outputDir = nextArg;\n i++; // Skip next argument\n break;\n case '--output-file':\n options.outputFileName = nextArg;\n i++; // Skip next argument\n break;\n case '--service-name':\n options.defaultServiceName = nextArg;\n i++; // Skip next argument\n break;\n case '--no-git':\n options.includeGitInfo = false;\n break;\n case '--no-ci':\n options.includeCiInfo = false;\n break;\n case '--help':\n console.log(`\nUsage: collect-build-info [options]\n\nOptions:\n --package-json-dir <path> Path to directory containing package.json (default: current directory)\n --output-dir <path> Path to output directory (default: src)\n --output-file <name> Name of output file (default: build-info.ts)\n --service-name <name> Default service name if not found in package.json\n --no-git Skip git information collection\n --no-ci Skip CI/CD information collection\n --help Show this help message\n `);\n process.exit(0);\n break;\n }\n }\n\n try {\n collectBuildInfo(options);\n } catch (error) {\n console.error('Error collecting build info:', error);\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}