Skip to content

Commit 900168f

Browse files
authored
Merge pull request #37 from telexintegrations/staging
Staging
2 parents 6fe2020 + 6ef7570 commit 900168f

File tree

9 files changed

+138
-240
lines changed

9 files changed

+138
-240
lines changed

README.md

Lines changed: 48 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
# Git Commit Quality Monitor
1+
# Git Commit Quality Monitor v2
22

33
A smart Telex integration that helps teams maintain high-quality git commit messages using ML-powered analysis and real-time feedback.
44

55
## Overview
66

77
Git Commit Quality Monitor analyzes commit messages in real-time, providing instant feedback on commit quality and suggestions for improvement. It uses machine learning to understand commit patterns and provides customized suggestions based on conventional commit standards and the development team's preferences.
88

9+
## Version Notes
10+
11+
- **v2 (current)**: Simplified architecture with pre-configured analysis rules
12+
- **v1-legacy**: Available in v1-legacy branch, supports configurable commit rules and dynamic analyzer settings
13+
914
### Key Features
1015

1116
- ⚡️ Real-time feedback through Slack
12-
- 🎯 Customizable commit rules/conventions
17+
- 🎯 Pre-configured commit standards based on conventional commits
1318
- 🔄 GitHub webhook integration
1419
- 🎨 Telex integration support
1520
- 🤖 Smart ML-powered commit message analysis and suggestions
@@ -46,38 +51,41 @@ Git Commit Quality Monitor analyzes commit messages in real-time, providing inst
4651
```
4752
project_root/
4853
├── src/
49-
│ ├── core/ # Core Analysis Engine
50-
│ │ ├── analyzer.py # ML-based commit analysis logic
51-
│ │ └── models.py # Data models and structure
54+
│ ├── core/ # Core Analysis Engine
55+
│ │ ├── analyzer/ # ML-based commit analysis logic
56+
| | | ├── analyzer.py
57+
| | | ├── format_analyzer.py
58+
| | | └── quality_analyzer.py
59+
│ │ └── models.py # Data models and structure
5260
│ │
53-
│ ├── config/ # Configuration Management
54-
│ │ ├── data.py # Training data, patterns, and examples
55-
│ │ ├── config.py # Environment settings management
56-
│ │ ├── integration_config.py # Telex integration configuration
57-
│ │ └── middleware.py # CORS and trusted host middleware
61+
│ ├── config/ # Configuration Management
62+
│ │ ├── data.py # Training data, patterns, and examples
63+
│ │ ├── config.py # Environment settings management
64+
│ │ ├── integration_config.py # Telex integration configuration
65+
│ │ └── middleware.py # CORS and trusted host middleware
5866
│ │
59-
│ ├── routers/ # API Routing Layer
60-
│ │ ├── github.py # GitHub webhook endpoint handling
61-
│ │ ├── telex.py # Telex webhook and integration
62-
│ │ └── router.py # Main router configuration
67+
│ ├── routers/ # API Routing Layer
68+
│ │ ├── github.py # GitHub webhook endpoint handling
69+
│ │ ├── telex.py # Telex webhook and integration
70+
│ │ └── router.py # Main router configuration
6371
│ │
64-
│ └── utils/ # Utility Functions
65-
│ └── telex_utils.py # Telex communication helpers
72+
│ └── utils/ # Utility Functions
73+
│ └── telex_utils.py # Telex communication helpers
6674
67-
├── tests/ # Test Suite
68-
│ ├── __init__.py # Test configuration
69-
│ ├── test_github.py # GitHub integration tests
70-
│ └── test_telex.py # Telex integration tests
75+
├── tests/ # Test Suite
76+
│ ├── __init__.py # Test configuration
77+
│ ├── test_github.py # GitHub integration tests
78+
│ └── test_telex.py # Telex integration tests
7179
72-
├── .env.example # Environment variable template
73-
├── main.py # Application entry point
74-
├── requirements.txt # Project dependencies
75-
└── README.md # Project documentation
80+
├── .env.example # Environment variable template
81+
├── main.py # Application entry point
82+
├── requirements.txt # Project dependencies
83+
└── README.md # Project documentation
7684
```
7785

7886
### Core Analysis Engine
7987

80-
The system implements a multi-step process to evaluate the quality of commit messages:
88+
The v2 system implements a multi-step process to evaluate the quality of commit messages:
8189

8290
#### Direct Pattern Matching
8391
- Matches against predefined commit types
@@ -143,7 +151,7 @@ semantic_patterns = {
143151

144152
### GitHub Webhook Endpoint
145153
```http
146-
POST /api/v1/webhook/github/{telex_channel_id}
154+
POST /api/v2/webhook/github/{telex_channel_id}/
147155
Content-Type: application/json
148156
149157
{
@@ -157,11 +165,11 @@ Content-Type: application/json
157165
]
158166
}
159167
```
160-
Receives GitHub push events and forwards to Telex.
168+
Receives GitHub push events, analyzes commits, and forwards to Telex.
161169

162170
### Telex Integration Endpoint
163171
```http
164-
POST /api/v1/webhook/telex
172+
POST /api/v2/webhook/telex/
165173
Content-Type: application/json
166174
167175
{
@@ -175,47 +183,17 @@ Content-Type: application/json
175183
]
176184
}
177185
```
178-
Receives commit messages from Telex and sends analysis results to slack.
186+
Receives commit messages from Telex and forwards to slack.
179187

180188
### Integration Config
181189
```
182190
GET /integration.json
183191
```
184192
Returns integration configuration for Telex.
185193

186-
### Customizing Commit Analysis
187-
188-
You can customize the analyzer through Telex integration settings:
189-
190-
#### Commit Types
191-
```json
192-
{
193-
"feat": ["add", "implement", "new"],
194-
"fix": ["fix", "resolve", "patch"]
195-
}
196-
```
197-
198-
#### Example Commits
199-
```json
200-
{
201-
"feat": "feat(auth): implement OAuth2 with role-based access\n\nImplemented OAuth2 protocol with role-based control to enhance security and scalability.",
202-
"fix": "fix(api): resolve data race in concurrent requests\n\nFixed a race condition by adding synchronization mechanisms to prevent concurrent data modifications."
203-
}
204-
```
205-
206-
#### Training Data
207-
```json
208-
{
209-
"feat": [
210-
"feat(auth): implement JWT authentication flow\n\nImplemented JWT-based authentication with token expiration handling to secure user sessions.",
211-
"feat(ui): add dark mode toggle with system preference detection\n\nAdded dark mode toggle that automatically adjusts based on system settings for improved user experience.",
212-
],
213-
}
214-
```
215-
216194
## Development Guide
217195

218-
### Basic Setup
196+
### Setting Up v2
219197

220198
1. Clone the repository:
221199
```bash
@@ -270,7 +248,7 @@ uvicorn main:app --reload
270248

271249
#### Step 3: Configure Webhook
272250
1. Fill in the following fields:
273-
- Payload URL: `https://your-domain/api/v1/webhook/github/{telex_channel_id}`
251+
- Payload URL: `https://your-domain/api/v2/webhook/github/{telex_channel_id}/`
274252
- Replace `your-domain` with your actual domain
275253
- Replace `{telex_channel_id}` with your Telex channel ID
276254
2. Set Content Type:
@@ -322,12 +300,20 @@ uvicorn main:app --reload
322300
- Click on "Manage App" beside the added integration
323301
- Click on "Settings"
324302
- Add the slack webhook in the `slack_url` field
325-
- Clear defaults in `commit_types`, `example_commits`, and `training_data` fields; replace with custom values if necessary.
326303

327304
#### Step 3: Save and Activate
328305
1. Click "Save Settings"
329306
2. Enable the integration on the Apps dashboard
330307

308+
### Using v1 (Legacy Version)
309+
310+
For teams requiring customizable features:
311+
1. Switch to v1-legacy branch:
312+
```bash
313+
git checkout v1-legacy
314+
```
315+
2. Follow setup instructions in v1-legacy README
316+
331317
### Testing Your Integration
332318

333319
#### Step 1: Make a Test Commit

src/config/integration_config.py

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ def generate_json_config():
2121
"integration_type": "output",
2222
"key_features": [
2323
"Smart commit message analysis with ML-powered suggestions",
24-
"Customizable commit rules that fit any team's style",
2524
"Instant notifications when commits need attention",
2625
"Easy setup with pre-configured commit patterns"
2726
],
28-
"website": settings.app_logo_url,
27+
"website": settings.app_url,
2928
"author": "iamprecieee",
3029
"settings": [
3130
{
@@ -34,27 +33,6 @@ def generate_json_config():
3433
"required": True,
3534
"description": "Slack Webhook URL",
3635
"default": "https://slack.com"
37-
},
38-
{
39-
"label": "commit_types",
40-
"type": "text",
41-
"required": False,
42-
"description": "Provide custom commit types mapped to keywords that indicate type of change. Format: {'type': ['keyword1', 'keyword2']}. Example: {'docs': ['document', 'readme']} means commits with 'document' or 'readme' suggest documentation changes.",
43-
"default": "{'feat': ['add', 'implement', 'new', 'introduce'], 'fix': ['fix', 'resolve', 'patch', 'address']}"
44-
},
45-
{
46-
"label": "example_commits",
47-
"type": "text",
48-
"required": False,
49-
"description": "Set example commits for each custom commit type to guide new devs. These appear in suggestions when similar commits need fixing. Format: {'type1': 'example message1', 'type2': 'example message 2'}.",
50-
"default": "{'feat': 'feat(auth): implement OAuth2 with role-based access\n\nImplemented OAuth2 protocol with role-based control to enhance security and scalability.', 'fix': 'fix(api): resolve data race in concurrent requests\n\nFixed a race condition by adding synchronization mechanisms to prevent concurrent data modifications.'}"
51-
},
52-
{
53-
"label": "training_data",
54-
"type": "text",
55-
"required": False,
56-
"description": "Add custom data to train the analyzer with commits that match preferred style. More examples = better suggestions. Format: {'type1': ['example1', 'example2'], 'type2': ['example3', 'example4']}. The analyzer learns from these to better match preferred conventions.",
57-
"default": "{'feat': ['feat(auth): implement OAuth2 with role-based access\n\nImplemented OAuth2 protocol with role-based control to enhance security and scalability.','feat(search): implement elasticsearch integration\n\nIntegrated Elasticsearch to boost search performance and enhance result accuracy.']}"
5836
}
5937
],
6038
"target_url": settings.target_url

src/core/analyzer/analyzer.py

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
example_commits,
44
commit_training_data
55
)
6-
from fastapi import HTTPException, status
76
from ..models import CommitIssue
87
from .format_analyzer import FormatAnalyzer
98
from .quality_analyzer import QualityAnalyzer
109
from datetime import datetime
11-
import ast
1210

1311

1412
class CommitAnalyzer:
@@ -17,38 +15,12 @@ class CommitAnalyzer:
1715
machine learning, and semantic analysis to ensure commit quality and
1816
provide improvement suggestions.
1917
"""
20-
def __init__(self, settings: list) -> None:
21-
"""Initializes the analyzer with custom settings and prepares the ML classifier."""
22-
self.settings = settings
23-
self.slack_url = None # Retrieved from settings
18+
def __init__(self) -> None:
19+
"""Initializes the analyzer with commit types, examples, and training data."""
2420
self.commit_types = commit_types
2521
self.example_commits = example_commits.copy()
2622
self.commit_training_data = commit_training_data.copy()
2723

28-
try:
29-
self._apply_data_settings()
30-
except Exception as e:
31-
raise HTTPException(
32-
status_code=status.HTTP_400_BAD_REQUEST,
33-
detail=f"Invalid settings data: {str(e)}",
34-
)
35-
36-
def _apply_data_settings(self) -> None:
37-
"""
38-
Updates analyzer configuration with custom settings provided through Telex.
39-
Custom settings can override default commit types, examples, and training data.
40-
Provides slack webhook url.
41-
"""
42-
for setting in self.settings:
43-
if setting["label"] == "commit_types":
44-
self.commit_types.update(ast.literal_eval(setting["default"].replace("\n", "\\n"))) if setting["default"] else self.commit_types
45-
if setting["label"] == "example_commits":
46-
self.example_commits.update(ast.literal_eval(setting["default"].replace("\n", "\\n"))) if setting["default"] else self.example_commits
47-
if setting["label"] == "training_data":
48-
self.commit_training_data.update(ast.literal_eval(setting["default"].replace("\n", "\\n"))) if setting["default"] else self.commit_training_data
49-
if setting["label"] == "slack_url":
50-
self.slack_url = setting["default"]
51-
5224
def _check_content_format(self, message: str) -> list[CommitIssue]:
5325
format_analyzer = FormatAnalyzer(message, self.commit_types, self.example_commits)
5426
return format_analyzer.check_all()

src/routers/github.py

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,55 @@
11
from fastapi.routing import APIRouter
22
from ..core.models import GitHubPayload, TelexWebhookPayload
3+
from typing import Annotated
4+
from ..core.analyzer.analyzer import CommitAnalyzer
35
from ..config.config import settings
46
from ..utils.telex_utils import send_payload
57
from fastapi.responses import JSONResponse
6-
from fastapi import status, HTTPException
8+
from fastapi import status, HTTPException, Query
79
import json
810

911

1012
router = APIRouter(prefix="/github")
1113

1214

13-
@router.post("/{telex_channel_id}", status_code=status.HTTP_200_OK)
14-
async def github_webhook(telex_channel_id: str, payload: GitHubPayload):
15-
"""Endpoint to receive GitHub webhook events and forward the commits to Telex."""
16-
telex_payload = TelexWebhookPayload(
17-
event_name="pushed_commits",
18-
message=str(payload.commits),
19-
status="success",
20-
username=payload.pusher["name"],
21-
).model_dump_json()
22-
23-
telex_url = f"{settings.telex_webhook_url}/{telex_channel_id}"
24-
25-
try:
26-
response = await send_payload(telex_payload, telex_url)
27-
response_data = json.loads(response.decode().strip())
28-
except Exception as e:
29-
raise HTTPException(
30-
status_code=status.HTTP_400_BAD_REQUEST,
31-
detail=f"Telex payload sending failed: {str(e)}",
32-
)
33-
34-
return JSONResponse(content={"data": response_data})
15+
@router.post("/{telex_channel_id}/", status_code=status.HTTP_200_OK)
16+
async def github_webhook(
17+
telex_channel_id: str,
18+
payload: GitHubPayload,
19+
is_test: Annotated[str | None, Query()] = None,
20+
):
21+
"""
22+
Endpoint to receive GitHub webhook events, analyze commit messages and
23+
send results to Telex if issues are found.
24+
"""
25+
analyzer = CommitAnalyzer()
26+
commits = payload.commits
27+
all_messages = [] # Accumulate messages for test mode
28+
29+
for commit in commits:
30+
violations = analyzer.analyze_commit(commit["message"])
31+
if violations:
32+
output_message = analyzer.format_analysis(commit, violations)
33+
if is_test == "true":
34+
all_messages.append(output_message)
35+
else:
36+
telex_payload = TelexWebhookPayload(
37+
event_name="pushed_commits",
38+
message=output_message,
39+
status="success",
40+
username=payload.pusher["name"],
41+
).model_dump_json()
42+
43+
telex_url = f"{settings.telex_webhook_url}/{telex_channel_id}"
44+
45+
try:
46+
await send_payload(telex_payload, telex_url)
47+
except Exception as e:
48+
raise HTTPException(
49+
status_code=status.HTTP_400_BAD_REQUEST,
50+
detail=f"Telex payload sending failed: {str(e)}",
51+
)
52+
if is_test == "true":
53+
return JSONResponse(content=all_messages, status_code=status.HTTP_200_OK)
54+
55+
return JSONResponse(content={"status": "success"})

src/routers/router.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
from .telex import router as telex_router
44

55

6-
webhook_router = APIRouter(prefix="/api/v1/webhook")
6+
webhook_router = APIRouter(prefix="/api/v2/webhook")
77
webhook_router.include_router(github_router)
88
webhook_router.include_router(telex_router)

0 commit comments

Comments
 (0)