Skip to content

Commit b6d8a24

Browse files
committed
Added jira integration
1 parent d6d0ef9 commit b6d8a24

File tree

13 files changed

+1543
-4
lines changed

13 files changed

+1543
-4
lines changed

JIRA_INTEGRATION.md

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# Jira Cloud Integration
2+
3+
This document describes how to set up and use the Jira Cloud integration with Wellcode CLI as an alternative to Linear for issue tracking metrics.
4+
5+
## Overview
6+
7+
The Jira Cloud integration provides comprehensive issue tracking analytics including:
8+
9+
- **Issue Flow Metrics**: Creation, completion, and in-progress tracking
10+
- **Issue Type Analysis**: Bugs, Stories, Tasks, and Epics breakdown
11+
- **Cycle Time Metrics**: Time from creation to resolution
12+
- **Estimation Accuracy**: Story points vs actual time analysis
13+
- **Project Performance**: Per-project metrics and health indicators
14+
- **Assignee Performance**: Individual contributor metrics
15+
- **Priority Distribution**: Issue priority analysis
16+
- **Component & Version Tracking**: Component and fix version metrics
17+
18+
## Prerequisites
19+
20+
1. **Jira Cloud Instance**: You need access to a Jira Cloud instance (*.atlassian.net)
21+
2. **API Token**: Generate an API token from your Atlassian account
22+
3. **Permissions**: Read access to projects and issues you want to analyze
23+
24+
## Setup Instructions
25+
26+
### 1. Generate Jira API Token
27+
28+
1. Go to [Atlassian Account Security](https://id.atlassian.com/manage-profile/security/api-tokens)
29+
2. Click "Create API token"
30+
3. Give it a descriptive name (e.g., "Wellcode CLI")
31+
4. Copy the generated token (you won't be able to see it again)
32+
33+
### 2. Configure Wellcode CLI
34+
35+
Run the configuration command:
36+
37+
```bash
38+
wellcode-cli config
39+
```
40+
41+
When prompted for Jira configuration, provide:
42+
43+
- **Domain**: Your Jira domain (e.g., `mycompany` for `mycompany.atlassian.net`)
44+
- **Email**: Your Atlassian account email address
45+
- **API Token**: The token you generated in step 1
46+
47+
The CLI will test the connection and save your configuration if successful.
48+
49+
### 3. Verify Setup
50+
51+
Test your configuration by running:
52+
53+
```bash
54+
wellcode-cli review
55+
```
56+
57+
You should see Jira metrics alongside your GitHub metrics.
58+
59+
## Usage
60+
61+
### Basic Usage
62+
63+
```bash
64+
# Review last 7 days (default)
65+
wellcode-cli review
66+
67+
# Review specific date range
68+
wellcode-cli review --start-date 2024-01-01 --end-date 2024-01-31
69+
70+
# Review specific user's issues
71+
wellcode-cli review --user "john.doe@company.com"
72+
```
73+
74+
### Filtering Options
75+
76+
- `--user`: Filter by assignee (use email address or Jira username)
77+
- `--start-date`: Start date for analysis (YYYY-MM-DD format)
78+
- `--end-date`: End date for analysis (YYYY-MM-DD format)
79+
80+
## Metrics Explained
81+
82+
### Issue Flow Metrics
83+
84+
- **Issues Created**: Total issues created in the time period
85+
- **Issues Completed**: Issues moved to "Done" status
86+
- **Completion Rate**: Percentage of created issues that were completed
87+
- **Issue Types**: Breakdown by Bugs, Stories, Tasks, and Epics
88+
89+
### Cycle Time Metrics
90+
91+
- **Average Cycle Time**: Mean time from creation to resolution
92+
- **Median Cycle Time**: 50th percentile cycle time
93+
- **95th Percentile**: 95th percentile cycle time (helps identify outliers)
94+
- **Resolution Time**: Time to close/resolve issues
95+
96+
### Estimation Accuracy
97+
98+
- **Accuracy Rate**: Percentage of estimates within 25% of actual time
99+
- **Underestimates**: Issues that took longer than estimated
100+
- **Overestimates**: Issues that took less time than estimated
101+
- **Variance**: Average percentage difference between estimate and actual
102+
103+
### Project Performance
104+
105+
- **Completion Rate**: Per-project completion percentage
106+
- **Issue Distribution**: Breakdown by issue types per project
107+
- **Assignee Involvement**: Number of people working on each project
108+
- **Project Lead**: Project lead information
109+
- **Project Type**: Software, Business, etc.
110+
111+
## Customization
112+
113+
### Story Points Field
114+
115+
The integration looks for story points in the `customfield_10016` field by default. If your Jira instance uses a different field for story points, you can modify this in the code:
116+
117+
```python
118+
# In src/wellcode_cli/jira/models/metrics.py
119+
story_points = fields.get("customfield_XXXXX") # Replace XXXXX with your field ID
120+
```
121+
122+
To find your story points field ID:
123+
1. Go to Jira Settings → Issues → Custom Fields
124+
2. Find your Story Points field
125+
3. Note the field ID (usually in the format `customfield_XXXXX`)
126+
127+
### Time Estimation
128+
129+
The integration supports both:
130+
- **Story Points**: Converted to hours (1 point = 4 hours by default)
131+
- **Time Estimates**: Original time estimates in Jira
132+
133+
## Troubleshooting
134+
135+
### Common Issues
136+
137+
1. **Authentication Failed**
138+
- Verify your email address is correct
139+
- Ensure your API token is valid and not expired
140+
- Check that your domain is correct (without .atlassian.net)
141+
142+
2. **No Issues Found**
143+
- Verify the date range includes issues
144+
- Check that you have read permissions for the projects
145+
- Ensure issues exist in the specified time period
146+
147+
3. **Missing Metrics**
148+
- Some metrics require specific Jira configurations (story points, time tracking)
149+
- Ensure your Jira instance has the required fields enabled
150+
151+
### Debug Mode
152+
153+
Enable debug logging to troubleshoot issues:
154+
155+
```bash
156+
export WELLCODE_DEBUG=1
157+
wellcode-cli review
158+
```
159+
160+
### API Rate Limits
161+
162+
Jira Cloud has API rate limits:
163+
- 300 requests per minute for most endpoints
164+
- The integration uses pagination to handle large datasets efficiently
165+
166+
## Security
167+
168+
- API tokens are stored locally in `~/.wellcode/config.json`
169+
- Tokens are transmitted over HTTPS only
170+
- No data is sent to external services except Jira Cloud
171+
172+
## Comparison with Linear
173+
174+
| Feature | Jira Cloud | Linear |
175+
|---------|------------|--------|
176+
| Issue Types | Bugs, Stories, Tasks, Epics | Issues with Labels |
177+
| Projects | Native project support | Team-based organization |
178+
| Time Tracking | Built-in time tracking | Estimation-based |
179+
| Custom Fields | Extensive customization | Limited custom fields |
180+
| Workflow | Configurable workflows | Fixed workflow states |
181+
| API Rate Limits | 300/minute | 1000/hour |
182+
183+
## Advanced Configuration
184+
185+
### Environment Variables
186+
187+
You can also configure Jira using environment variables:
188+
189+
```bash
190+
export JIRA_DOMAIN="mycompany"
191+
export JIRA_EMAIL="user@company.com"
192+
export JIRA_API_KEY="your-api-token"
193+
```
194+
195+
### JQL Customization
196+
197+
The integration uses JQL (Jira Query Language) to fetch issues. The default query is:
198+
199+
```jql
200+
created >= 'YYYY-MM-DD' AND created <= 'YYYY-MM-DD'
201+
```
202+
203+
For advanced users, you can modify the JQL in `src/wellcode_cli/jira/jira_metrics.py`.
204+
205+
## Support
206+
207+
For issues with the Jira integration:
208+
209+
1. Check the troubleshooting section above
210+
2. Enable debug mode for detailed logs
211+
3. Verify your Jira permissions and configuration
212+
4. Create an issue in the Wellcode CLI repository with debug logs
213+
214+
## Contributing
215+
216+
To contribute to the Jira integration:
217+
218+
1. Fork the repository
219+
2. Create a feature branch
220+
3. Add tests for new functionality
221+
4. Submit a pull request
222+
223+
The Jira integration follows the same patterns as other integrations in the codebase for consistency and maintainability.

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<strong>Engineering Metrics Powered by AI</strong>
99
</p>
1010
<p align="center">
11-
Free, open-source CLI tool that integrates with GitHub, Linear, and Split.io to gather and analyze engineering team metrics.
11+
Free, open-source CLI tool that integrates with GitHub, Linear, Jira Cloud, and Split.io to gather and analyze engineering team metrics.
1212
</p>
1313

1414
## 🚀 Installation
@@ -27,6 +27,7 @@ wellcode-cli config
2727
This will guide you through:
2828
- GitHub App installation for your organization
2929
- Optional Linear integration
30+
- Optional Jira Cloud integration
3031
- Optional Split.io integration
3132
- Optional Anthropic integration (for AI-powered insights)
3233

@@ -88,6 +89,7 @@ wellcode-cli
8889

8990
### Optional Integrations
9091
- **Linear**: Issue tracking metrics
92+
- **Jira Cloud**: Issue tracking metrics (alternative to Linear)
9193
- **Split.io**: Feature flag analytics
9294
- **Anthropic**: AI-powered insights
9395

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ rich>=13.3.5
1010
plotly
1111
markdown
1212
cryptography>=43.0.1
13+
requests
1314
types-requests
1415
types-python-dateutil
1516
pandas-stubs

src/wellcode_cli/commands/config.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from ..github.app_config import WELLCODE_APP
1010
from ..github.auth import clear_user_token, get_user_token
1111
from ..github.client import GithubClient
12+
from ..jira.jira_metrics import test_jira_connection
1213

1314
console = Console()
1415
CONFIG_FILE = Path.home() / ".wellcode" / "config.json"
@@ -111,13 +112,19 @@ def config():
111112
# Optional integrations with secret masking
112113
optional_configs = {
113114
"Linear": ("LINEAR_API_KEY", "Enter your Linear API key"),
115+
"Jira": ("JIRA_API_KEY", "Enter your Jira API key"),
114116
"Split.io": ("SPLIT_API_KEY", "Enter your Split.io API key"),
115117
"Anthropic": ("ANTHROPIC_API_KEY", "Enter your Anthropic API key"),
116118
}
117119

118120
for name, (key, prompt) in optional_configs.items():
119121
console.print(f"\n[bold cyan]{name} Configuration[/]")
120-
handle_sensitive_config(config_data, name, key, prompt)
122+
123+
# Special handling for Jira to get additional required fields
124+
if name == "Jira":
125+
handle_jira_config(config_data)
126+
else:
127+
handle_sensitive_config(config_data, name, key, prompt)
121128

122129
# Save configuration
123130
CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
@@ -134,8 +141,14 @@ def config():
134141
console.print("[green]✓ GitHub App installed and configured[/]")
135142

136143
for name, (key, _) in optional_configs.items():
137-
status = "✓" if key in config_data else "✗"
138-
color = "green" if key in config_data else "red"
144+
if name == "Jira":
145+
# Special check for Jira which requires multiple fields
146+
has_jira = all(k in config_data for k in ["JIRA_DOMAIN", "JIRA_EMAIL", "JIRA_API_KEY"])
147+
status = "✓" if has_jira else "✗"
148+
color = "green" if has_jira else "red"
149+
else:
150+
status = "✓" if key in config_data else "✗"
151+
color = "green" if key in config_data else "red"
139152
console.print(f"[{color}]{status} {name}[/]")
140153

141154
console.print("\n✅ [green]Configuration saved successfully![/]")
@@ -184,3 +197,67 @@ def handle_sensitive_config(config_data, name, key, prompt_text):
184197
value = Prompt.ask(prompt_text)
185198
if value:
186199
config_data[key] = value
200+
201+
202+
def handle_jira_config(config_data):
203+
"""Handle Jira configuration with domain, email, and API key"""
204+
has_jira_config = all(key in config_data for key in ["JIRA_DOMAIN", "JIRA_EMAIL", "JIRA_API_KEY"])
205+
206+
if has_jira_config:
207+
console.print("[yellow]Jira integration is already configured[/]")
208+
choice = Prompt.ask(
209+
"Would you like to reconfigure Jira?",
210+
choices=["y", "n", "clear"],
211+
default="n",
212+
)
213+
214+
if choice == "y":
215+
configure_jira_details(config_data)
216+
elif choice == "clear":
217+
for key in ["JIRA_DOMAIN", "JIRA_EMAIL", "JIRA_API_KEY"]:
218+
if key in config_data:
219+
del config_data[key]
220+
console.print("[yellow]Jira configuration cleared[/]")
221+
else:
222+
if Confirm.ask("Would you like to configure Jira integration?", default=False):
223+
configure_jira_details(config_data)
224+
225+
226+
def configure_jira_details(config_data):
227+
"""Configure Jira domain, email, and API key"""
228+
console.print("\n[bold]Jira Cloud Configuration[/]")
229+
console.print("You'll need:")
230+
console.print("1. Your Jira domain (e.g., 'mycompany' for mycompany.atlassian.net)")
231+
console.print("2. Your email address")
232+
console.print("3. An API token from https://id.atlassian.com/manage-profile/security/api-tokens")
233+
234+
# Get domain
235+
current_domain = config_data.get("JIRA_DOMAIN", "")
236+
domain = Prompt.ask("Enter your Jira domain", default=current_domain)
237+
if not domain:
238+
console.print("[red]Domain is required for Jira integration[/]")
239+
return
240+
241+
# Get email
242+
current_email = config_data.get("JIRA_EMAIL", "")
243+
email = Prompt.ask("Enter your email address", default=current_email)
244+
if not email:
245+
console.print("[red]Email is required for Jira integration[/]")
246+
return
247+
248+
# Get API key
249+
api_key = Prompt.ask("Enter your Jira API token")
250+
if not api_key:
251+
console.print("[red]API token is required for Jira integration[/]")
252+
return
253+
254+
# Test the connection
255+
console.print("\n[yellow]Testing Jira connection...[/]")
256+
if test_jira_connection(domain, email, api_key):
257+
config_data["JIRA_DOMAIN"] = domain
258+
config_data["JIRA_EMAIL"] = email
259+
config_data["JIRA_API_KEY"] = api_key
260+
console.print("[green]✓ Jira configuration saved successfully![/]")
261+
else:
262+
console.print("[red]✗ Jira connection failed. Configuration not saved.[/]")
263+
console.print("Please check your domain, email, and API token.")

0 commit comments

Comments
 (0)