A Python project for tracking and analyzing Git repositories using Domain-Driven Development (DDD) architecture.
Also available as a reusable GitHub Action! See GitHub Action Usage below.
Git Ticker is designed to provide tools and services for working with Git repositories, including validation utilities and analysis capabilities. The project follows a clean architecture pattern with clear separation of concerns.
- AI-Powered Commit Summarization: Generate detailed markdown summaries for commits using LLM agents:
- Processes commits in a range (from commit A to commit B) and generates one markdown file per commit
- Generates a single unified summary of all changes from a development branch relative to a main branch (using
--dev-branch) - Files are named with sequence number and commit hash for easy ordering and identification (commit range mode)
- Console output for development branch diff summaries
- Python 3.12+
- Poetry (for dependency management)
- Git (for repository operations)
- Clone the repository:
git clone <repository-url>
cd gitlab-ticker- Install dependencies using Poetry:
poetry install- Activate the virtual environment:
poetry shell- Configure environment variables:
- Copy
.env.exampleto.env(if it exists) or create a.envfile - Set the required API keys (see Configuration section below)
- Copy
The validate_commits.py script validates git repository parameters and optionally generates AI-powered commit summaries. It supports two modes:
Process commits between two specific commit hashes:
python validate_commits.py <repo_path> <branch_name> <commit_a> [commit_b] [--output OUTPUT_DIR] [--skip-summarization] [--skip-empty-merges]Parameters:
repo_path: Path to the git repository directorybranch_name: Name of the branchcommit_a: Hash of the older commit (commit A)commit_b: (Optional) Hash of the newer commit (commit B). If not provided, defaults to the latest commit on the specified branch--output,-o: (Optional) Output directory path where commit summaries will be saved. Defaults to./output--skip-summarization: (Optional) Skip summarization and only validate parameters--skip-empty-merges: (Optional) Skip merge commits that contain no file changes. When enabled, merge commits without modifications are excluded from summarization, reducing output size and focusing on commits with actual code changes.
Generate a single summary of all changes between a development branch and the main branch:
python validate_commits.py <repo_path> <main_branch> --dev-branch <dev_branch> [--skip-summarization] [--max-diff-size MAX_SIZE] [--send-to-slack] [--slack-channel CHANNEL]Parameters:
repo_path: Path to the git repository directorymain_branch: Name of the main branch (e.g.,main,master)--dev-branch: Name of the development branch. When specified, the script finds the merge base (creation point) between the two branches and generates a single summary of all changes from the merge base to the latest commit on the development branch--skip-summarization: (Optional) Skip summarization and only validate parameters--max-diff-size: (Optional) Maximum diff size in characters before truncation (default: 50000)--send-to-slack: (Optional) Send the summary to a Slack channel (requires--slack-channel)--slack-channel: (Optional) Slack channel name without the # prefix (required if--send-to-slackis set)--summary-template: (Optional) Path to a custom summary template file (markdown). Defaults to the built-in template
Note:
- When using
--dev-branch,commit_aandcommit_bare not required - The script automatically finds the merge base (the commit where the development branch was created) and the latest commit on the development branch
- The summary is displayed in the console (not saved to files)
- This mode generates a single unified summary of all changes, rather than individual summaries per commit
Commit Summarization: When summarization is enabled (default), the script generates detailed markdown summaries for each commit in the range:
- Creates a
commits_summaries/directory in the output directory - Generates one markdown file per commit with the format:
{sequence:04d}_{commit_hash[:8]}.md- Example:
0001_a1b2c3d4.md,0002_b2c3d4e5.md, etc.
- Example:
- Sequence numbers start at 1 and correspond to the commit order in the branch (oldest to newest)
- When
--skip-empty-mergesis used, filtered commits are excluded and sequence numbers are recalculated to maintain continuous numbering - Each file contains the full markdown summary generated by the LLM agent
Examples:
Commit Range Mode:
# Validate and generate summaries
python validate_commits.py /path/to/repo main abc123 def456
# Specify custom output directory
python validate_commits.py /path/to/repo main abc123 def456 --output ./my_summaries
# Skip empty merge commits (merge commits with no file changes)
python validate_commits.py /path/to/repo main abc123 def456 --skip-empty-merges
# Only validate without generating summaries
python validate_commits.py /path/to/repo main abc123 --skip-summarizationDevelopment Branch Diff Mode:
# Generate a single summary of all changes from feature branch relative to main branch
python validate_commits.py /path/to/repo main --dev-branch feature/new-feature
# With custom max diff size
python validate_commits.py /path/to/repo main --dev-branch feature/new-feature --max-diff-size 100000
# Send summary to Slack channel
python validate_commits.py /path/to/repo main --dev-branch feature/new-feature \
--send-to-slack --slack-channel team-updatesSlack Integration:
To send the summary to a Slack channel in dev-branch mode:
python validate_commits.py /path/to/repo main --dev-branch feature/new-feature \
--send-to-slack --slack-channel generalRequirements:
- Set
SLACK_TOKENenvironment variable with your Slack Bot User OAuth Token - The bot must be invited to the target channel
- Channel name should be without the # prefix (use
generalnot#general)
How to get a Slack token:
- Go to https://api.slack.com/apps
- Create a new app or select an existing one
- Navigate to "OAuth & Permissions"
- Add the
chat:writebot token scope - Install the app to your workspace
- Copy the "Bot User OAuth Token" (starts with
xoxb-) - Invite the bot to your channel:
/invite @your-bot-name
Note: In dev-branch mode, the summary is displayed directly in the console. The --output and --skip-empty-merges options are not applicable in this mode.
Exit Codes:
0: All parameters are valid (and summaries generated if not skipped)1: Validation failed or summarization error with error message
This project is available as a reusable GitHub Action that you can use in your workflows.
Add this to your workflow file (.github/workflows/summarize.yml):
name: Summarize PR Changes
on:
pull_request:
types: [opened, synchronize]
jobs:
summarize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for git history
- name: Generate PR Summary
uses: RossinesP/git-ticker@v1
with:
mode: 'dev-branch'
main_branch: 'main'
dev_branch: ${{ github.head_ref }}
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}| Input | Description | Required | Default |
|---|---|---|---|
mode |
Operation mode: commit-range or dev-branch |
Yes | dev-branch |
repo_path |
Path to the git repository | No | . |
main_branch |
Name of the main branch | Yes | main |
dev_branch |
Development branch name (for dev-branch mode) |
Conditional | - |
commit_a |
Older commit hash (for commit-range mode) |
Conditional | - |
commit_b |
Newer commit hash (for commit-range mode) |
No | Latest |
output_dir |
Output directory for summaries | No | ./output |
skip_empty_merges |
Skip merge commits with no changes | No | false |
max_diff_size |
Max diff size before truncation | No | 50000 |
llm_provider |
LLM provider: anthropic or openai |
No | anthropic |
anthropic_api_key |
Anthropic API key | Conditional | - |
anthropic_model |
Anthropic model name | No | claude-3-5-sonnet-20241022 |
openai_api_key |
OpenAI API key | Conditional | - |
openai_model |
OpenAI model name | No | gpt-4-turbo-preview |
send_to_slack |
Send summary to Slack | No | false |
slack_token |
Slack Bot OAuth Token | Conditional | - |
slack_channel |
Slack channel name (without #) | Conditional | - |
summary_template |
Path to custom summary template file | No | Built-in |
| Output | Description |
|---|---|
summary |
Generated summary (dev-branch mode) |
output_path |
Path to output directory (commit-range mode) |
name: PR Summary to Slack
on:
pull_request:
types: [opened, ready_for_review]
jobs:
summarize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate and Send Summary
uses: RossinesP/git-ticker@v1
with:
mode: 'dev-branch'
main_branch: 'main'
dev_branch: ${{ github.head_ref }}
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
send_to_slack: 'true'
slack_token: ${{ secrets.SLACK_TOKEN }}
slack_channel: 'pr-reviews'name: Summarize Release Commits
on:
workflow_dispatch:
inputs:
from_commit:
description: 'Start commit hash'
required: true
to_commit:
description: 'End commit hash'
required: true
jobs:
summarize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate Commit Summaries
uses: RossinesP/git-ticker@v1
with:
mode: 'commit-range'
main_branch: 'main'
commit_a: ${{ github.event.inputs.from_commit }}
commit_b: ${{ github.event.inputs.to_commit }}
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
output_dir: './summaries'
- name: Upload Summaries
uses: actions/upload-artifact@v4
with:
name: commit-summaries
path: ./summaries- name: Generate Summary with OpenAI
uses: RossinesP/git-ticker@v1
with:
mode: 'dev-branch'
main_branch: 'main'
dev_branch: ${{ github.head_ref }}
llm_provider: 'openai'
openai_api_key: ${{ secrets.OPENAI_API_KEY }}
openai_model: 'gpt-4-turbo-preview'You can customize the output format of generated summaries by providing your own template file. The template defines the structure and sections that the LLM should use when generating summaries.
CLI:
python validate_commits.py /path/to/repo main --dev-branch feature/my-feature \
--summary-template /path/to/my-template.mdGitHub Action:
- name: Generate Summary with Custom Template
uses: RossinesP/git-ticker@v1
with:
mode: 'dev-branch'
main_branch: 'main'
dev_branch: ${{ github.head_ref }}
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
summary_template: '.github/templates/summary-template.md'The template file should contain instructions for the LLM about how to structure its output. Here's an example custom template:
You MUST structure your response using exactly these sections in markdown format:
## 🎯 Overview
Provide a single sentence describing the changes.
## 📝 Changes
List the main changes made:
- Feature additions
- Bug fixes
- Refactoring
## 📁 Files Modified
List the key files that were modified.
## ⚠️ Important Notes
Include any breaking changes, migration steps, or security considerations.The default template is located at git_ticker/summarization/templates/default_summary_template.md and can be used as a reference.
Configure these secrets in your repository settings:
ANTHROPIC_API_KEY: Your Anthropic API key (if using Anthropic)OPENAI_API_KEY: Your OpenAI API key (if using OpenAI)SLACK_TOKEN: Slack Bot OAuth Token (if using Slack notifications)
The project uses environment variables for configuration. Create a .env file in the project root with the following variables:
LLM Provider Configuration:
LLM_PROVIDER: Set to"anthropic"or"openai"to choose the LLM provider (default:"anthropic")
Anthropic API Configuration:
ANTHROPIC_API_KEY: Your Anthropic API key (required if using Anthropic)ANTHROPIC_MODEL: Model name to use (default:"claude-3-5-sonnet-20241022")
OpenAI API Configuration:
OPENAI_API_KEY: Your OpenAI API key (required if using OpenAI)OPENAI_MODEL: Model name to use (default:"gpt-4-turbo-preview")
Slack Notification Configuration:
SLACK_TOKEN: Your Slack Bot User OAuth Token (required for Slack notifications)
LangSmith Observability Configuration:
LANGCHAIN_API_KEY: Your LangSmith API key (get it from https://smith.langchain.com/)LANGCHAIN_TRACING_V2: Set to"true"to enable LangSmith tracing (optional, but recommended)LANGCHAIN_PROJECT: Project name in LangSmith dashboard (optional, defaults to"default")
LangSmith provides comprehensive observability for LLM operations in this project. Once configured, it automatically traces:
- All LLM API calls (Anthropic Claude and OpenAI)
- Input messages and system prompts
- LLM responses and outputs
- Tool calls and function invocations
- Performance metrics (latency, token usage, costs)
- Errors and exceptions
Setup:
- Sign up for a free account at https://smith.langchain.com/
- Get your API key from the LangSmith dashboard
- Add
LANGCHAIN_API_KEYto your.envfile - Set
LANGCHAIN_TRACING_V2=trueto enable tracing - Optionally set
LANGCHAIN_PROJECTto organize traces in your dashboard
Benefits:
- Debugging: Inspect exact prompts and responses for each commit summarization
- Monitoring: Track performance and costs across all LLM operations
- Optimization: Identify slow or expensive operations
- Quality Assurance: Review generated summaries and improve prompts
The tracing works automatically with no code changes required - LangChain integrates seamlessly with LangSmith when the environment variables are set.
The project follows a Domain-Driven Development (DDD) architecture:
git_ticker/
<domain_name>/
domain/ # Domain entities and value objects
repositories/ # Repository interfaces and implementations
services/ # Business services
See .cursorrules for detailed architecture guidelines.
- Install dependencies:
poetry install - Add a dependency:
poetry add <package> - Add a development dependency:
poetry add --group dev <package> - Activate virtual environment:
poetry shell - Run commands in virtual environment:
poetry run <command> - Update dependencies:
poetry update
- All code, documentation, and comments must be in English
- Follow DDD architecture principles
- Write unit tests for domains, repositories, and services
- Keep README.md updated when adding new features
- All code must be fully typed with type hints (annotations)
The project uses ty for type checking and ruff for linting and code formatting.
Check type correctness:
poetry run ty checkAll code must pass ty type checks before committing. The project is configured with strict type checking enabled.
Check code quality and style:
poetry run ruff check .Format code:
poetry run ruff format .The project uses isort to ensure consistent import ordering across all Python files, following PEP 8 guidelines.
Check import ordering:
poetry run isort . --check-only --diffFormat imports automatically:
poetry run isort .Import Order:
- Standard library imports
- Third-party imports
- Local application/library specific imports (
git_ticker)
Important: Every code change must be validated by ty, ruff, and isort before completion. Fix all errors and warnings before committing code. Always run poetry run isort . after modifying imports to ensure consistent ordering.
[Add license information here]
- Pierre Rossinès pierre.rossines@gmail.com