@kabran-tecnologia/kabran-config 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +283 -0
- package/package.json +63 -8
- package/src/schemas/ci-result.v2.schema.json +125 -0
- package/src/scripts/ci/ci-runner.sh +85 -0
- package/src/scripts/ci-result-history.mjs +245 -0
- package/src/scripts/ci-result-trends.mjs +296 -0
- package/src/scripts/ci-result-utils.mjs +104 -0
- package/src/scripts/generate-ci-result.mjs +79 -11
- package/src/scripts/pr-quality-comment.mjs +36 -0
- package/src/scripts/setup.mjs +91 -4
- package/src/telemetry/config/defaults.mjs +421 -0
- package/src/telemetry/config/index.mjs +132 -0
- package/src/telemetry/edge/index.mjs +446 -0
- package/src/telemetry/frontend/index.mjs +366 -0
- package/src/telemetry/logger/index.mjs +236 -0
- package/src/telemetry/node/index.mjs +386 -0
- package/src/telemetry/shared/helpers.mjs +133 -0
- package/src/telemetry/shared/index.mjs +15 -0
- package/src/telemetry/shared/types.d.ts +123 -0
- package/templates/telemetry/.env.telemetry.example +118 -0
package/README.md
CHANGED
|
@@ -888,6 +888,283 @@ For detailed migration instructions from existing CI/CD scripts, see [CI-CD-MIGR
|
|
|
888
888
|
|
|
889
889
|
---
|
|
890
890
|
|
|
891
|
+
## Telemetry (OpenTelemetry)
|
|
892
|
+
|
|
893
|
+
Unified observability for Kabran projects. Distributed tracing, error tracking, and performance monitoring using OpenTelemetry.
|
|
894
|
+
|
|
895
|
+
> **Optional Feature:** Telemetry dependencies are optional. Only install them if your project needs observability.
|
|
896
|
+
|
|
897
|
+
### Quick Start
|
|
898
|
+
|
|
899
|
+
```javascript
|
|
900
|
+
// Frontend (React/Vite)
|
|
901
|
+
import { initTelemetry, createSpan } from '@kabran-tecnologia/kabran-config/telemetry/frontend'
|
|
902
|
+
|
|
903
|
+
initTelemetry({ serviceName: 'my-app' })
|
|
904
|
+
|
|
905
|
+
// Edge Functions (Supabase/Deno)
|
|
906
|
+
import { withTelemetry, traceSupabaseQuery } from '@kabran-tecnologia/kabran-config/telemetry/edge'
|
|
907
|
+
|
|
908
|
+
serve(withTelemetry('my-function', async (req, span) => {
|
|
909
|
+
const result = await traceSupabaseQuery('select', 'users', () => supabase.from('users').select())
|
|
910
|
+
return new Response(JSON.stringify(result.data))
|
|
911
|
+
}))
|
|
912
|
+
|
|
913
|
+
// Node.js Backend
|
|
914
|
+
import { initTelemetry, telemetryMiddleware } from '@kabran-tecnologia/kabran-config/telemetry/node'
|
|
915
|
+
|
|
916
|
+
await initTelemetry({ serviceName: 'my-api' })
|
|
917
|
+
app.use(telemetryMiddleware())
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
### Installation
|
|
921
|
+
|
|
922
|
+
Install the required peer dependencies only if using telemetry:
|
|
923
|
+
|
|
924
|
+
```bash
|
|
925
|
+
npm install --save-dev \
|
|
926
|
+
@opentelemetry/api@^1.9 \
|
|
927
|
+
@opentelemetry/sdk-trace-base@^1.28 \
|
|
928
|
+
@opentelemetry/exporter-trace-otlp-http@^0.56 \
|
|
929
|
+
@opentelemetry/resources@^1.28 \
|
|
930
|
+
@opentelemetry/semantic-conventions@^1.28 \
|
|
931
|
+
@opentelemetry/core@^1.28
|
|
932
|
+
|
|
933
|
+
# Frontend additional
|
|
934
|
+
npm install --save-dev \
|
|
935
|
+
@opentelemetry/sdk-trace-web@^1.28 \
|
|
936
|
+
@opentelemetry/instrumentation@^0.56 \
|
|
937
|
+
@opentelemetry/instrumentation-fetch@^0.56 \
|
|
938
|
+
@opentelemetry/instrumentation-document-load@^0.43 \
|
|
939
|
+
@opentelemetry/instrumentation-user-interaction@^0.43
|
|
940
|
+
|
|
941
|
+
# Node.js additional
|
|
942
|
+
npm install --save-dev @opentelemetry/sdk-trace-node@^1.28
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
### Frontend Module
|
|
946
|
+
|
|
947
|
+
For browser/frontend applications (React, Vue, etc.):
|
|
948
|
+
|
|
949
|
+
```javascript
|
|
950
|
+
// main.tsx or App.tsx
|
|
951
|
+
import { initTelemetry, createSpan, createAsyncSpan } from '@kabran-tecnologia/kabran-config/telemetry/frontend'
|
|
952
|
+
|
|
953
|
+
// Initialize at app startup
|
|
954
|
+
initTelemetry({
|
|
955
|
+
serviceName: 'my-frontend',
|
|
956
|
+
serviceVersion: '1.0.0',
|
|
957
|
+
endpoint: 'https://otel.example.com',
|
|
958
|
+
})
|
|
959
|
+
|
|
960
|
+
// Create custom spans for tracking operations
|
|
961
|
+
function handleCheckout(items) {
|
|
962
|
+
return createSpan('checkout.process', (span) => {
|
|
963
|
+
span.setAttribute('items.count', items.length)
|
|
964
|
+
return processCheckout(items)
|
|
965
|
+
})
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// Async operations
|
|
969
|
+
async function fetchUserData(userId) {
|
|
970
|
+
return createAsyncSpan('user.fetch', async (span) => {
|
|
971
|
+
span.setAttribute('user.id', userId)
|
|
972
|
+
const response = await fetch(`/api/users/${userId}`)
|
|
973
|
+
return response.json()
|
|
974
|
+
})
|
|
975
|
+
}
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
**Auto-instrumentation included:**
|
|
979
|
+
|
|
980
|
+
- Fetch API requests
|
|
981
|
+
- Document load performance
|
|
982
|
+
- User interactions (click, submit)
|
|
983
|
+
- Global error handlers
|
|
984
|
+
|
|
985
|
+
### Edge Module (Supabase/Deno)
|
|
986
|
+
|
|
987
|
+
For serverless/edge functions with immediate trace export:
|
|
988
|
+
|
|
989
|
+
```javascript
|
|
990
|
+
import { serve } from 'https://deno.land/std/http/server.ts'
|
|
991
|
+
import { withTelemetry, traceSupabaseQuery, getTraceId } from '@kabran-tecnologia/kabran-config/telemetry/edge'
|
|
992
|
+
|
|
993
|
+
serve(withTelemetry('user-api', async (req, span) => {
|
|
994
|
+
// Automatic HTTP attributes (method, url, status)
|
|
995
|
+
span.setAttribute('custom.attribute', 'value')
|
|
996
|
+
|
|
997
|
+
// Trace database queries
|
|
998
|
+
const { data, error } = await traceSupabaseQuery('select', 'users', () =>
|
|
999
|
+
supabase.from('users').select('*').limit(10)
|
|
1000
|
+
)
|
|
1001
|
+
|
|
1002
|
+
if (error) {
|
|
1003
|
+
return new Response(JSON.stringify({ error: error.message }), { status: 500 })
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
return new Response(JSON.stringify({ data, trace_id: getTraceId() }))
|
|
1007
|
+
}))
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
**Features:**
|
|
1011
|
+
|
|
1012
|
+
- W3C Trace Context propagation
|
|
1013
|
+
- SimpleSpanProcessor for immediate export (serverless-friendly)
|
|
1014
|
+
- Supabase query wrapper with automatic attributes
|
|
1015
|
+
- Error response includes trace_id for debugging
|
|
1016
|
+
|
|
1017
|
+
### Node.js Module
|
|
1018
|
+
|
|
1019
|
+
For Node.js backends with Express/Fastify:
|
|
1020
|
+
|
|
1021
|
+
```javascript
|
|
1022
|
+
import express from 'express'
|
|
1023
|
+
import { initTelemetry, telemetryMiddleware, createSpan } from '@kabran-tecnologia/kabran-config/telemetry/node'
|
|
1024
|
+
|
|
1025
|
+
const app = express()
|
|
1026
|
+
|
|
1027
|
+
// Initialize before routes
|
|
1028
|
+
await initTelemetry({
|
|
1029
|
+
serviceName: 'my-api',
|
|
1030
|
+
serviceVersion: '1.0.0',
|
|
1031
|
+
})
|
|
1032
|
+
|
|
1033
|
+
// Add middleware (creates spans for all requests)
|
|
1034
|
+
app.use(telemetryMiddleware({
|
|
1035
|
+
ignorePaths: ['/health', '/ready', '/metrics'],
|
|
1036
|
+
}))
|
|
1037
|
+
|
|
1038
|
+
// Access span in handlers via req.span
|
|
1039
|
+
app.get('/users/:id', async (req, res) => {
|
|
1040
|
+
req.span.setAttribute('user.id', req.params.id)
|
|
1041
|
+
const user = await getUserById(req.params.id)
|
|
1042
|
+
res.json(user)
|
|
1043
|
+
})
|
|
1044
|
+
|
|
1045
|
+
// Graceful shutdown on SIGTERM/SIGINT
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
**Features:**
|
|
1049
|
+
|
|
1050
|
+
- BatchSpanProcessor for efficient export
|
|
1051
|
+
- Express/Fastify middleware
|
|
1052
|
+
- Automatic request/response tracing
|
|
1053
|
+
- Parent context extraction from headers
|
|
1054
|
+
- Process signal handlers for graceful shutdown
|
|
1055
|
+
|
|
1056
|
+
### Logger Module
|
|
1057
|
+
|
|
1058
|
+
Structured logging with trace correlation:
|
|
1059
|
+
|
|
1060
|
+
```javascript
|
|
1061
|
+
import { createLogger, createSpanLogger } from '@kabran-tecnologia/kabran-config/telemetry/logger'
|
|
1062
|
+
|
|
1063
|
+
// Basic logger
|
|
1064
|
+
const logger = createLogger({
|
|
1065
|
+
name: 'my-service',
|
|
1066
|
+
level: 'info',
|
|
1067
|
+
format: 'json', // or 'pretty'
|
|
1068
|
+
})
|
|
1069
|
+
|
|
1070
|
+
logger.info('User logged in', { userId: '123' })
|
|
1071
|
+
|
|
1072
|
+
// Span-aware logger (adds events to active span)
|
|
1073
|
+
const spanLogger = createSpanLogger(span)
|
|
1074
|
+
spanLogger.info('Processing started')
|
|
1075
|
+
spanLogger.error('Processing failed', { error: err.message })
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
### Configuration
|
|
1079
|
+
|
|
1080
|
+
Configuration is resolved from multiple sources (in order of precedence):
|
|
1081
|
+
|
|
1082
|
+
1. Explicit config object
|
|
1083
|
+
2. Environment variables (Vite-style: `VITE_*`)
|
|
1084
|
+
3. Environment variables (Node-style: `OTEL_*`)
|
|
1085
|
+
4. Smart defaults
|
|
1086
|
+
|
|
1087
|
+
**Environment Variables:**
|
|
1088
|
+
|
|
1089
|
+
| Variable | Vite Equivalent | Description | Default |
|
|
1090
|
+
|----------|-----------------|-------------|---------|
|
|
1091
|
+
| `OTEL_ENDPOINT` | `VITE_OTEL_ENDPOINT` | Collector endpoint URL | - |
|
|
1092
|
+
| `OTEL_ENABLED` | `VITE_OTEL_ENABLED` | Enable/disable telemetry | `true` in prod |
|
|
1093
|
+
| `SERVICE_NAME` | `VITE_SERVICE_NAME` | Service identifier | Required |
|
|
1094
|
+
| `SERVICE_VERSION` | `VITE_SERVICE_VERSION` | Service version | `1.0.0` |
|
|
1095
|
+
| `ENVIRONMENT` | `VITE_ENVIRONMENT` | Deployment environment | `development` |
|
|
1096
|
+
| `OTEL_SAMPLE_RATE` | `VITE_OTEL_SAMPLE_RATE` | Sampling rate (0.0-1.0) | `0.1` (10%) |
|
|
1097
|
+
|
|
1098
|
+
**Programmatic Configuration:**
|
|
1099
|
+
|
|
1100
|
+
```javascript
|
|
1101
|
+
import { defineTelemetryConfig } from '@kabran-tecnologia/kabran-config/telemetry/config'
|
|
1102
|
+
|
|
1103
|
+
const config = defineTelemetryConfig({
|
|
1104
|
+
serviceName: 'my-service',
|
|
1105
|
+
serviceVersion: '1.0.0',
|
|
1106
|
+
endpoint: 'https://otel.example.com',
|
|
1107
|
+
environment: 'production',
|
|
1108
|
+
sampleRate: 0.5, // 50% sampling
|
|
1109
|
+
instrumentation: {
|
|
1110
|
+
fetch: true,
|
|
1111
|
+
documentLoad: true,
|
|
1112
|
+
userInteraction: false,
|
|
1113
|
+
},
|
|
1114
|
+
resourceAttributes: {
|
|
1115
|
+
'deployment.region': 'us-east-1',
|
|
1116
|
+
},
|
|
1117
|
+
})
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
### API Reference
|
|
1121
|
+
|
|
1122
|
+
**Frontend (`telemetry/frontend`):**
|
|
1123
|
+
|
|
1124
|
+
- `initTelemetry(config)` - Initialize OpenTelemetry
|
|
1125
|
+
- `getTracer(name?)` - Get tracer instance
|
|
1126
|
+
- `getCurrentSpan()` - Get active span
|
|
1127
|
+
- `getTraceId()` - Get current trace ID
|
|
1128
|
+
- `createSpan(name, fn, attrs?)` - Create sync span
|
|
1129
|
+
- `createAsyncSpan(name, fn, attrs?)` - Create async span
|
|
1130
|
+
- `addSpanEvent(name, attrs?)` - Add event to current span
|
|
1131
|
+
- `setSpanAttributes(attrs)` - Set attributes on current span
|
|
1132
|
+
- `shutdownTelemetry()` - Graceful shutdown
|
|
1133
|
+
- `isInitialized()` - Check if initialized
|
|
1134
|
+
- `getConfig()` - Get resolved config
|
|
1135
|
+
|
|
1136
|
+
**Edge (`telemetry/edge`):**
|
|
1137
|
+
|
|
1138
|
+
- `withTelemetry(name, handler, config?)` - Wrap request handler
|
|
1139
|
+
- `traceSupabaseQuery(op, table, fn)` - Wrap Supabase query
|
|
1140
|
+
- `extractContext(headers)` - Extract W3C trace context
|
|
1141
|
+
- `injectContext(headers)` - Inject W3C trace context
|
|
1142
|
+
- `getTracer(name?)`, `getCurrentSpan()`, `getTraceId()`
|
|
1143
|
+
- `createSpan()`, `createAsyncSpan()`, `addSpanEvent()`, `setSpanAttributes()`
|
|
1144
|
+
- `shutdownTelemetry()`
|
|
1145
|
+
|
|
1146
|
+
**Node (`telemetry/node`):**
|
|
1147
|
+
|
|
1148
|
+
- `initTelemetry(config)` - Initialize OpenTelemetry
|
|
1149
|
+
- `telemetryMiddleware(options?)` - Express/Fastify middleware
|
|
1150
|
+
- `getTracer(name?)`, `getCurrentSpan()`, `getTraceId()`
|
|
1151
|
+
- `createSpan()`, `createAsyncSpan()`, `addSpanEvent()`, `setSpanAttributes()`
|
|
1152
|
+
- `shutdownTelemetry()`, `isInitialized()`, `getConfig()`
|
|
1153
|
+
|
|
1154
|
+
**Logger (`telemetry/logger`):**
|
|
1155
|
+
|
|
1156
|
+
- `createLogger(options)` - Create structured logger
|
|
1157
|
+
- `createSpanLogger(span)` - Create span-aware logger
|
|
1158
|
+
|
|
1159
|
+
**Config (`telemetry/config`):**
|
|
1160
|
+
|
|
1161
|
+
- `defineTelemetryConfig(config)` - Define configuration
|
|
1162
|
+
- `resolveConfig(config, env, mode)` - Resolve from sources
|
|
1163
|
+
- `validateConfig(config)` - Validate configuration
|
|
1164
|
+
- `detectEnabled(mode, env)` - Auto-detect if enabled
|
|
1165
|
+
|
|
1166
|
+
---
|
|
1167
|
+
|
|
891
1168
|
## What's Included
|
|
892
1169
|
|
|
893
1170
|
| Config | Description |
|
|
@@ -909,6 +1186,12 @@ For detailed migration instructions from existing CI/CD scripts, see [CI-CD-MIGR
|
|
|
909
1186
|
| `@kabran-tecnologia/kabran-config/scripts/ci/*` | Standardized CI pipeline runner and core functions |
|
|
910
1187
|
| `@kabran-tecnologia/kabran-config/scripts/deploy/*` | Standardized deployment orchestration |
|
|
911
1188
|
| `@kabran-tecnologia/kabran-config/scripts/setup` | Project setup CLI (`npx kabran-setup`) |
|
|
1189
|
+
| `@kabran-tecnologia/kabran-config/telemetry/config` | Telemetry configuration and validation |
|
|
1190
|
+
| `@kabran-tecnologia/kabran-config/telemetry/frontend` | OpenTelemetry for browser/frontend apps |
|
|
1191
|
+
| `@kabran-tecnologia/kabran-config/telemetry/edge` | OpenTelemetry for Supabase/Deno edge functions |
|
|
1192
|
+
| `@kabran-tecnologia/kabran-config/telemetry/node` | OpenTelemetry for Node.js backends |
|
|
1193
|
+
| `@kabran-tecnologia/kabran-config/telemetry/logger` | Structured logging with trace correlation |
|
|
1194
|
+
| `@kabran-tecnologia/kabran-config/telemetry/shared` | Shared telemetry utilities and types |
|
|
912
1195
|
|
|
913
1196
|
---
|
|
914
1197
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kabran-tecnologia/kabran-config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Shared quality configurations, enforcement scripts, and CI/CD tooling for Kabran projects",
|
|
5
5
|
"author": "Kabran",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,8 +33,16 @@
|
|
|
33
33
|
"./scripts/quality-standard-validator": "./src/scripts/quality-standard-validator.mjs",
|
|
34
34
|
"./scripts/generate-ci-result": "./src/scripts/generate-ci-result.mjs",
|
|
35
35
|
"./scripts/ci-result-utils": "./src/scripts/ci-result-utils.mjs",
|
|
36
|
+
"./scripts/ci-result-history": "./src/scripts/ci-result-history.mjs",
|
|
37
|
+
"./scripts/ci-result-trends": "./src/scripts/ci-result-trends.mjs",
|
|
36
38
|
"./scripts/pr-quality-comment": "./src/scripts/pr-quality-comment.mjs",
|
|
37
|
-
"./schemas/ci-result": "./src/schemas/ci-result.v2.schema.json"
|
|
39
|
+
"./schemas/ci-result": "./src/schemas/ci-result.v2.schema.json",
|
|
40
|
+
"./telemetry/config": "./src/telemetry/config/index.mjs",
|
|
41
|
+
"./telemetry/frontend": "./src/telemetry/frontend/index.mjs",
|
|
42
|
+
"./telemetry/edge": "./src/telemetry/edge/index.mjs",
|
|
43
|
+
"./telemetry/node": "./src/telemetry/node/index.mjs",
|
|
44
|
+
"./telemetry/logger": "./src/telemetry/logger/index.mjs",
|
|
45
|
+
"./telemetry/shared": "./src/telemetry/shared/index.mjs"
|
|
38
46
|
},
|
|
39
47
|
"files": [
|
|
40
48
|
"src",
|
|
@@ -52,6 +60,9 @@
|
|
|
52
60
|
"ci",
|
|
53
61
|
"cd",
|
|
54
62
|
"deployment",
|
|
63
|
+
"telemetry",
|
|
64
|
+
"opentelemetry",
|
|
65
|
+
"observability",
|
|
55
66
|
"kabran"
|
|
56
67
|
],
|
|
57
68
|
"repository": {
|
|
@@ -76,7 +87,19 @@
|
|
|
76
87
|
"prettier": ">=3.0.0",
|
|
77
88
|
"prettier-plugin-tailwindcss": ">=0.5.0",
|
|
78
89
|
"typescript": ">=5.0.0",
|
|
79
|
-
"typescript-eslint": ">=8.0.0"
|
|
90
|
+
"typescript-eslint": ">=8.0.0",
|
|
91
|
+
"@opentelemetry/api": ">=1.9.0",
|
|
92
|
+
"@opentelemetry/sdk-trace-web": ">=1.28.0",
|
|
93
|
+
"@opentelemetry/sdk-trace-node": ">=1.28.0",
|
|
94
|
+
"@opentelemetry/sdk-trace-base": ">=1.28.0",
|
|
95
|
+
"@opentelemetry/exporter-trace-otlp-http": ">=0.56.0",
|
|
96
|
+
"@opentelemetry/resources": ">=1.28.0",
|
|
97
|
+
"@opentelemetry/semantic-conventions": ">=1.28.0",
|
|
98
|
+
"@opentelemetry/core": ">=1.28.0",
|
|
99
|
+
"@opentelemetry/instrumentation": ">=0.56.0",
|
|
100
|
+
"@opentelemetry/instrumentation-fetch": ">=0.56.0",
|
|
101
|
+
"@opentelemetry/instrumentation-document-load": ">=0.43.0",
|
|
102
|
+
"@opentelemetry/instrumentation-user-interaction": ">=0.43.0"
|
|
80
103
|
},
|
|
81
104
|
"peerDependenciesMeta": {
|
|
82
105
|
"eslint-plugin-jsdoc": {
|
|
@@ -84,6 +107,42 @@
|
|
|
84
107
|
},
|
|
85
108
|
"prettier-plugin-tailwindcss": {
|
|
86
109
|
"optional": true
|
|
110
|
+
},
|
|
111
|
+
"@opentelemetry/api": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
114
|
+
"@opentelemetry/sdk-trace-web": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
117
|
+
"@opentelemetry/sdk-trace-node": {
|
|
118
|
+
"optional": true
|
|
119
|
+
},
|
|
120
|
+
"@opentelemetry/sdk-trace-base": {
|
|
121
|
+
"optional": true
|
|
122
|
+
},
|
|
123
|
+
"@opentelemetry/exporter-trace-otlp-http": {
|
|
124
|
+
"optional": true
|
|
125
|
+
},
|
|
126
|
+
"@opentelemetry/resources": {
|
|
127
|
+
"optional": true
|
|
128
|
+
},
|
|
129
|
+
"@opentelemetry/semantic-conventions": {
|
|
130
|
+
"optional": true
|
|
131
|
+
},
|
|
132
|
+
"@opentelemetry/core": {
|
|
133
|
+
"optional": true
|
|
134
|
+
},
|
|
135
|
+
"@opentelemetry/instrumentation": {
|
|
136
|
+
"optional": true
|
|
137
|
+
},
|
|
138
|
+
"@opentelemetry/instrumentation-fetch": {
|
|
139
|
+
"optional": true
|
|
140
|
+
},
|
|
141
|
+
"@opentelemetry/instrumentation-document-load": {
|
|
142
|
+
"optional": true
|
|
143
|
+
},
|
|
144
|
+
"@opentelemetry/instrumentation-user-interaction": {
|
|
145
|
+
"optional": true
|
|
87
146
|
}
|
|
88
147
|
},
|
|
89
148
|
"scripts": {
|
|
@@ -96,10 +155,6 @@
|
|
|
96
155
|
},
|
|
97
156
|
"devDependencies": {
|
|
98
157
|
"bats": "^1.11.0",
|
|
99
|
-
"vitest": "^4.0.17"
|
|
100
|
-
"semantic-release": "^24.0.0",
|
|
101
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
102
|
-
"@semantic-release/git": "^10.0.1",
|
|
103
|
-
"conventional-changelog-conventionalcommits": "^8.0.0"
|
|
158
|
+
"vitest": "^4.0.17"
|
|
104
159
|
}
|
|
105
160
|
}
|
|
@@ -45,6 +45,10 @@
|
|
|
45
45
|
"commit": {
|
|
46
46
|
"type": "string",
|
|
47
47
|
"description": "Git commit SHA (short or full)"
|
|
48
|
+
},
|
|
49
|
+
"trace_id": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "OpenTelemetry trace ID for correlation with observability data"
|
|
48
52
|
}
|
|
49
53
|
}
|
|
50
54
|
},
|
|
@@ -222,11 +226,132 @@
|
|
|
222
226
|
"extensions": {
|
|
223
227
|
"type": "object",
|
|
224
228
|
"description": "Custom extensions for project-specific data",
|
|
229
|
+
"properties": {
|
|
230
|
+
"telemetry": {
|
|
231
|
+
"$ref": "#/$defs/telemetryExtension"
|
|
232
|
+
}
|
|
233
|
+
},
|
|
225
234
|
"additionalProperties": true,
|
|
226
235
|
"default": {}
|
|
236
|
+
},
|
|
237
|
+
"trends": {
|
|
238
|
+
"type": "object",
|
|
239
|
+
"description": "Trend analysis based on historical CI runs",
|
|
240
|
+
"properties": {
|
|
241
|
+
"score": {
|
|
242
|
+
"$ref": "#/$defs/metricTrend"
|
|
243
|
+
},
|
|
244
|
+
"performance": {
|
|
245
|
+
"$ref": "#/$defs/metricTrend"
|
|
246
|
+
},
|
|
247
|
+
"issues": {
|
|
248
|
+
"$ref": "#/$defs/metricTrend"
|
|
249
|
+
},
|
|
250
|
+
"data": {
|
|
251
|
+
"type": "object",
|
|
252
|
+
"properties": {
|
|
253
|
+
"total_runs": {
|
|
254
|
+
"type": "integer",
|
|
255
|
+
"minimum": 0,
|
|
256
|
+
"description": "Total number of historical runs analyzed"
|
|
257
|
+
},
|
|
258
|
+
"branch_filter": {
|
|
259
|
+
"type": ["string", "null"],
|
|
260
|
+
"description": "Branch filter applied to history"
|
|
261
|
+
},
|
|
262
|
+
"calculated_at": {
|
|
263
|
+
"type": "string",
|
|
264
|
+
"format": "date-time",
|
|
265
|
+
"description": "When trends were calculated"
|
|
266
|
+
},
|
|
267
|
+
"date_range": {
|
|
268
|
+
"type": "object",
|
|
269
|
+
"properties": {
|
|
270
|
+
"from": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"format": "date-time"
|
|
273
|
+
},
|
|
274
|
+
"to": {
|
|
275
|
+
"type": "string",
|
|
276
|
+
"format": "date-time"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
227
283
|
}
|
|
228
284
|
},
|
|
229
285
|
"$defs": {
|
|
286
|
+
"metricTrend": {
|
|
287
|
+
"type": "object",
|
|
288
|
+
"description": "Trend data for a single metric",
|
|
289
|
+
"properties": {
|
|
290
|
+
"direction": {
|
|
291
|
+
"type": "string",
|
|
292
|
+
"enum": ["improving", "degrading", "stable"],
|
|
293
|
+
"description": "Trend direction"
|
|
294
|
+
},
|
|
295
|
+
"current": {
|
|
296
|
+
"type": ["number", "null"],
|
|
297
|
+
"description": "Current value"
|
|
298
|
+
},
|
|
299
|
+
"change_7d": {
|
|
300
|
+
"type": ["number", "null"],
|
|
301
|
+
"description": "Change over last 7 days"
|
|
302
|
+
},
|
|
303
|
+
"change_30d": {
|
|
304
|
+
"type": ["number", "null"],
|
|
305
|
+
"description": "Change over last 30 days"
|
|
306
|
+
},
|
|
307
|
+
"avg_7d": {
|
|
308
|
+
"type": ["number", "null"],
|
|
309
|
+
"description": "7-day average"
|
|
310
|
+
},
|
|
311
|
+
"avg_30d": {
|
|
312
|
+
"type": ["number", "null"],
|
|
313
|
+
"description": "30-day average"
|
|
314
|
+
},
|
|
315
|
+
"data_points": {
|
|
316
|
+
"type": "integer",
|
|
317
|
+
"minimum": 0,
|
|
318
|
+
"description": "Number of data points used"
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"telemetryExtension": {
|
|
323
|
+
"type": "object",
|
|
324
|
+
"description": "OpenTelemetry integration data",
|
|
325
|
+
"properties": {
|
|
326
|
+
"trace_id": {
|
|
327
|
+
"type": "string",
|
|
328
|
+
"description": "Trace ID for correlation"
|
|
329
|
+
},
|
|
330
|
+
"enabled": {
|
|
331
|
+
"type": "boolean",
|
|
332
|
+
"description": "Whether telemetry is enabled"
|
|
333
|
+
},
|
|
334
|
+
"trace_url": {
|
|
335
|
+
"type": "string",
|
|
336
|
+
"format": "uri",
|
|
337
|
+
"description": "URL to view the trace"
|
|
338
|
+
},
|
|
339
|
+
"spans_exported": {
|
|
340
|
+
"type": "integer",
|
|
341
|
+
"minimum": 0,
|
|
342
|
+
"description": "Number of spans exported"
|
|
343
|
+
},
|
|
344
|
+
"errors_recorded": {
|
|
345
|
+
"type": "integer",
|
|
346
|
+
"minimum": 0,
|
|
347
|
+
"description": "Number of errors recorded"
|
|
348
|
+
},
|
|
349
|
+
"collector_endpoint": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"description": "OTel collector endpoint"
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
},
|
|
230
355
|
"step": {
|
|
231
356
|
"type": "object",
|
|
232
357
|
"description": "Individual step result",
|
|
@@ -10,6 +10,64 @@ set -euo pipefail
|
|
|
10
10
|
RUNNER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
CORE_SCRIPT="$RUNNER_DIR/ci-core.sh"
|
|
12
12
|
|
|
13
|
+
# ==============================================================================
|
|
14
|
+
# Command Line Arguments
|
|
15
|
+
# ==============================================================================
|
|
16
|
+
|
|
17
|
+
show_help() {
|
|
18
|
+
cat << EOF
|
|
19
|
+
Usage: $(basename "$0") [options]
|
|
20
|
+
|
|
21
|
+
Kabran CI Runner - Execute project CI pipelines
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
--list-scopes List available scopes from ci-config.sh and exit
|
|
25
|
+
--scope <name> Run only the specified scope (component)
|
|
26
|
+
--help Show this help message and exit
|
|
27
|
+
|
|
28
|
+
Environment Variables:
|
|
29
|
+
CI_SCOPE Set the scope filter (default: all)
|
|
30
|
+
CI_VERBOSE Enable verbose output (default: false)
|
|
31
|
+
CI_OUTPUT_FILE Output file for legacy v1 format
|
|
32
|
+
CI_OUTPUT_FILE_V2 Output file for v2 format (default: docs/quality/ci-result.json)
|
|
33
|
+
CI_CONFIG_FILE Path to project ci-config.sh
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
# Run all steps
|
|
37
|
+
$(basename "$0")
|
|
38
|
+
|
|
39
|
+
# Run only specific component
|
|
40
|
+
$(basename "$0") --scope app
|
|
41
|
+
|
|
42
|
+
# List available scopes
|
|
43
|
+
$(basename "$0") --list-scopes
|
|
44
|
+
EOF
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
LIST_SCOPES=false
|
|
48
|
+
|
|
49
|
+
while [[ $# -gt 0 ]]; do
|
|
50
|
+
case $1 in
|
|
51
|
+
--list-scopes)
|
|
52
|
+
LIST_SCOPES=true
|
|
53
|
+
shift
|
|
54
|
+
;;
|
|
55
|
+
--scope)
|
|
56
|
+
CI_SCOPE="$2"
|
|
57
|
+
shift 2
|
|
58
|
+
;;
|
|
59
|
+
--help|-h)
|
|
60
|
+
show_help
|
|
61
|
+
exit 0
|
|
62
|
+
;;
|
|
63
|
+
*)
|
|
64
|
+
echo "Unknown option: $1" >&2
|
|
65
|
+
show_help
|
|
66
|
+
exit 1
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
done
|
|
70
|
+
|
|
13
71
|
# Load core functions
|
|
14
72
|
if [ ! -f "$CORE_SCRIPT" ]; then
|
|
15
73
|
echo "ERROR: ci-core.sh not found at $CORE_SCRIPT" >&2
|
|
@@ -58,6 +116,33 @@ fi
|
|
|
58
116
|
log_info "Loading project configuration: $CONFIG_FILE"
|
|
59
117
|
source "$CONFIG_FILE"
|
|
60
118
|
|
|
119
|
+
# ==============================================================================
|
|
120
|
+
# List Scopes (if requested)
|
|
121
|
+
# ==============================================================================
|
|
122
|
+
|
|
123
|
+
if [ "$LIST_SCOPES" = "true" ]; then
|
|
124
|
+
echo "Available scopes in $PROJECT_NAME:"
|
|
125
|
+
echo ""
|
|
126
|
+
|
|
127
|
+
# Check if CI_COMPONENTS is defined (common pattern for monorepos)
|
|
128
|
+
if [ -n "${CI_COMPONENTS:-}" ]; then
|
|
129
|
+
echo "Components:"
|
|
130
|
+
for component in $CI_COMPONENTS; do
|
|
131
|
+
echo " - $component"
|
|
132
|
+
done
|
|
133
|
+
elif declare -f list_scopes >/dev/null; then
|
|
134
|
+
# Project can define custom list_scopes function
|
|
135
|
+
list_scopes
|
|
136
|
+
else
|
|
137
|
+
echo " all (single project - no components defined)"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
echo ""
|
|
141
|
+
echo "Usage: CI_SCOPE=<scope> $(basename "$0")"
|
|
142
|
+
echo " or: $(basename "$0") --scope <scope>"
|
|
143
|
+
exit 0
|
|
144
|
+
fi
|
|
145
|
+
|
|
61
146
|
# ==============================================================================
|
|
62
147
|
# Validate Configuration
|
|
63
148
|
# ==============================================================================
|