diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..bab6f2d --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,378 @@ +# GitHub Actions Workflow Documentation + +## Monthly Developer Report Workflow + +Automated workflow that generates developer performance reports from Azure DevOps work items. + +### Features + +- **Scheduled Execution**: Automatically runs on the 30th of every month at 23:00 UTC +- **Manual Trigger**: Run on-demand with custom date ranges and developer filters +- **Automatic Artifact Storage**: Reports saved for 90 days +- **Performance Optimized**: Uses `--optimized` flag for faster execution + +--- + +## Setup Instructions + +### 1. Configure GitHub Secrets + +The workflow requires two secrets to be configured in the `main` environment: + +1. Go to your GitHub repository +2. Navigate to **Settings** → **Environments** → **main** (create if it doesn't exist) +3. Add the following secrets: + +| Secret Name | Description | Example | +|-------------|-------------|---------| +| `AZURE_DEVOPS_ORG` | Your Azure DevOps organization name | `MyCompany` | +| `AZURE_DEVOPS_PAT` | Personal Access Token with Work Items: Read permission | `a1b2c3d4...` | + +**To create a PAT:** +- Go to Azure DevOps → User Settings → Personal Access Tokens +- Click "New Token" +- Set expiration and scope: **Work Items: Read** +- Copy the generated token immediately + +### 2. Enable GitHub Actions + +1. Go to **Settings** → **Actions** → **General** +2. Ensure "Allow all actions and reusable workflows" is selected +3. Save changes + +--- + +## Usage + +### Automatic Monthly Reports + +The workflow automatically runs on the **30th of each month at 23:00 UTC** and generates a report for: +- **Start Date**: 1st of the current month +- **End Date**: 30th of the current month +- **Developers**: Uses default list from `config/azure_devops_config.json` + +**Default Developers** (from config): +- Luis Nocedal +- Carlos Vazquez +- Fernando Alcaraz +- Rodrigo Mendoza +- Jorge Hernandez + +**Output Files:** +- `developer_report_YYYY-MM.csv` (detailed work items) +- `developer_report_YYYY-MM_developer_summary.csv` (aggregated metrics) + +### Manual Execution + +Run the workflow manually with custom parameters: + +1. Go to **Actions** tab in your repository +2. Select **"Monthly Developer Report"** workflow +3. Click **"Run workflow"** button +4. Fill in the parameters: + +#### Parameters + +| Parameter | Required | Description | Example | +|-----------|----------|-------------|---------| +| `start_date` | Yes | Start date for the report | `2025-09-01` | +| `end_date` | Yes | End date for the report | `2025-09-30` | +| `assigned_to` | No | Comma-separated developer names (leave empty for all) | `John Doe,Jane Smith` | + +5. Click **"Run workflow"** + +### Example Manual Runs + +**Generate report for September 2025:** +- start_date: `2025-09-01` +- end_date: `2025-09-30` +- assigned_to: *(leave empty)* + +**Generate report for specific developers:** +- start_date: `2025-10-01` +- end_date: `2025-10-15` +- assigned_to: `Developer1,Developer2` + +**Generate quarterly report:** +- start_date: `2025-07-01` +- end_date: `2025-09-30` +- assigned_to: *(leave empty)* + +--- + +## Output Files + +### File Naming Convention + +**Scheduled runs:** +- `developer_report_YYYY-MM.csv` +- `developer_report_YYYY-MM_developer_summary.csv` + +**Manual runs:** +- `developer_report_YYYY-MM-DD_to_YYYY-MM-DD.csv` +- `developer_report_YYYY-MM-DD_to_YYYY-MM-DD_developer_summary.csv` + +### Downloading Reports + +1. Go to the **Actions** tab +2. Click on the workflow run +3. Scroll to **Artifacts** section +4. Download `developer-report-[date-range].zip` +5. Extract to access CSV files + +### Artifact Retention + +Reports are stored for **90 days** after generation. Download important reports before they expire. + +--- + +## Workflow Details + +### Scheduled Execution + +```yaml +schedule: + - cron: '0 23 30 * *' # 23:00 UTC on the 30th of every month +``` + +**Note:** GitHub Actions cron uses UTC timezone. Adjust if needed for your timezone. + +### Manual Trigger + +```yaml +workflow_dispatch: + inputs: + start_date: YYYY-MM-DD (required) + end_date: YYYY-MM-DD (required) + assigned_to: Comma-separated names (optional) +``` + +### Workflow Steps + +1. **Checkout repository** - Clone the code +2. **Set up Python** - Install Python 3.11 with pip caching +3. **Install dependencies** - Install from `requirements.txt` +4. **Calculate date range** - Determine dates based on trigger type +5. **Generate report** - Run the CLI tool with optimized settings +6. **Upload artifacts** - Save reports for download +7. **Create summary** - Display execution summary in GitHub UI + +--- + +## Troubleshooting + +### Workflow Fails with Authentication Error + +**Problem:** `Authentication failed` or `401 Unauthorized` + +**Solution:** +1. Verify `AZURE_DEVOPS_PAT` secret is correctly set +2. Ensure PAT has not expired +3. Confirm PAT has `Work Items: Read` permission +4. Check `AZURE_DEVOPS_ORG` matches your organization name exactly + +### No Reports Generated + +**Problem:** Workflow completes but no artifacts uploaded + +**Solution:** +1. Check workflow logs for Python errors +2. Verify date range contains work items +3. Ensure developers have work items assigned in that period +4. Check `run.py` script exists in repository root + +### Scheduled Run Doesn't Execute + +**Problem:** Workflow doesn't run on the 30th + +**Solution:** +1. Verify GitHub Actions are enabled in repository settings +2. Check if the repository is active (GitHub may disable Actions on inactive repos) +3. Note: Scheduled runs may be delayed during high GitHub load +4. Manually trigger the workflow to verify it works + +### Reports Are Empty or Incomplete + +**Problem:** CSV files are generated but contain no data + +**Solution:** +1. Check date range matches actual work item activity +2. Verify work items are in the expected states (Closed, Done, etc.) +3. Ensure developers are correctly assigned to work items +4. Try using `--all-projects` flag (requires workflow modification) + +--- + +## Customization + +### Modify Default Developer List + +Edit `config/azure_devops_config.json`: + +```json +{ + "work_item_query": { + ... + "default_developers": [ + "Developer Name 1", + "Developer Name 2", + "Developer Name 3" + ] + } +} +``` + +The workflow will automatically use this list for scheduled runs. Manual runs can still override with custom developer names. + +### Modify Scheduled Time + +Edit `.github/workflows/monthly-developer-report.yml`: + +```yaml +schedule: + - cron: '0 9 1 * *' # 09:00 UTC on the 1st of every month +``` + +Cron syntax: `minute hour day-of-month month day-of-week` + +### Change Date Range for Scheduled Runs + +Edit the "Calculate date range" step: + +```bash +# Example: Generate report for previous month +START_DATE=$(date -d "last month" +%Y-%m-01) +END_DATE=$(date -d "last month" +%Y-%m-%d) +``` + +### Add Additional CLI Options + +Edit the "Generate developer report" step: + +```bash +CMD="python run.py --query-work-items \ + --start-date ${{ steps.dates.outputs.start_date }} \ + --end-date ${{ steps.dates.outputs.end_date }} \ + --optimized \ + --max-workers 15 \ + --work-item-types 'Task,Bug' \ + --export-csv developer_report_${{ steps.dates.outputs.filename_suffix }}.csv" +``` + +### Enable Email Notifications + +Add a notification step at the end of the workflow: + +```yaml +- name: Send email notification + uses: dawidd6/action-send-mail@v3 + with: + server_address: smtp.gmail.com + server_port: 465 + username: ${{ secrets.EMAIL_USERNAME }} + password: ${{ secrets.EMAIL_PASSWORD }} + subject: Monthly Developer Report - ${{ steps.dates.outputs.filename_suffix }} + body: Report generated successfully. Download from GitHub Actions artifacts. + to: team@company.com + from: noreply@company.com +``` + +--- + +## Advanced Configuration + +### Run for Multiple Developer Groups + +Create separate workflow files for different teams: + +```yaml +# .github/workflows/team-frontend-report.yml +- name: Generate frontend team report + run: | + python run.py --query-work-items \ + --assigned-to "FrontendDev1,FrontendDev2,FrontendDev3" \ + --start-date ${{ steps.dates.outputs.start_date }} \ + --end-date ${{ steps.dates.outputs.end_date }} \ + --export-csv frontend_team_report.csv +``` + +### Store Reports in Cloud Storage + +Add a step to upload to AWS S3, Azure Blob, or Google Cloud Storage: + +```yaml +- name: Upload to Azure Blob Storage + uses: azure/CLI@v1 + with: + inlineScript: | + az storage blob upload \ + --account-name ${{ secrets.STORAGE_ACCOUNT }} \ + --container-name reports \ + --name developer_report_${{ steps.dates.outputs.filename_suffix }}.csv \ + --file developer_report_${{ steps.dates.outputs.filename_suffix }}.csv +``` + +### Create GitHub Release with Reports + +Automatically create a release with attached reports: + +```yaml +- name: Create Release + uses: softprops/action-gh-release@v1 + with: + tag_name: report-${{ steps.dates.outputs.filename_suffix }} + name: Developer Report - ${{ steps.dates.outputs.filename_suffix }} + files: | + developer_report_${{ steps.dates.outputs.filename_suffix }}.csv + developer_report_${{ steps.dates.outputs.filename_suffix }}_developer_summary.csv +``` + +--- + +## Monitoring + +### View Workflow Execution History + +1. Go to **Actions** tab +2. Select **"Monthly Developer Report"** workflow +3. View all past runs with status and duration + +### Check Workflow Status + +- **Green checkmark**: Successful execution +- **Red X**: Failed execution (check logs) +- **Yellow dot**: Currently running +- **Gray circle**: Queued or waiting + +### Workflow Logs + +Click on any workflow run to view detailed logs for each step, including: +- Python dependency installation +- Report generation output +- File sizes and developer counts +- Error messages (if any) + +--- + +## Security Best Practices + +1. **Never commit PAT tokens** to the repository +2. **Use environment protection rules** to restrict who can run workflows +3. **Rotate PATs regularly** (recommended: every 90 days) +4. **Use minimal PAT permissions** (only Work Items: Read) +5. **Enable audit logging** for sensitive operations +6. **Review workflow run logs** for suspicious activity + +--- + +## Support + +For issues with the workflow: +1. Check the **Troubleshooting** section above +2. Review workflow run logs in the Actions tab +3. Verify secrets are correctly configured +4. Test the CLI command locally first + +For issues with the Azure DevOps CLI tool itself: +- Refer to the main [README.md](../../README.md) +- Check [documentation/](../../documentation/) folder diff --git a/.github/workflows/monthly-developer-report.yml b/.github/workflows/monthly-developer-report.yml new file mode 100644 index 0000000..16064a1 --- /dev/null +++ b/.github/workflows/monthly-developer-report.yml @@ -0,0 +1,135 @@ +name: Monthly Developer Report + +on: + # Scheduled to run on the 30th of every month at 23:00 UTC + schedule: + - cron: '0 23 30 * *' + + # Manual trigger with customizable date range + workflow_dispatch: + inputs: + start_date: + description: 'Start date (YYYY-MM-DD)' + required: true + type: string + end_date: + description: 'End date (YYYY-MM-DD)' + required: true + type: string + assigned_to: + description: 'Comma-separated list of developers (leave empty for all)' + required: false + type: string + default: '' + +jobs: + generate-report: + runs-on: ubuntu-latest + environment: main + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: 'pip' + + - name: Install dependencies + run: | + pip install -r requirements.txt + + - name: Calculate date range for scheduled run + id: dates + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Manual trigger - use provided dates + echo "start_date=${{ inputs.start_date }}" >> $GITHUB_OUTPUT + echo "end_date=${{ inputs.end_date }}" >> $GITHUB_OUTPUT + echo "filename_suffix=${{ inputs.start_date }}_to_${{ inputs.end_date }}" >> $GITHUB_OUTPUT + else + # Scheduled run - first to 30th of current month + YEAR=$(date +%Y) + MONTH=$(date +%m) + START_DATE="${YEAR}-${MONTH}-01" + END_DATE="${YEAR}-${MONTH}-30" + echo "start_date=${START_DATE}" >> $GITHUB_OUTPUT + echo "end_date=${END_DATE}" >> $GITHUB_OUTPUT + echo "filename_suffix=${YEAR}-${MONTH}" >> $GITHUB_OUTPUT + fi + + - name: Load default developers from config + id: config + run: | + # Extract default_developers from config file + DEFAULT_DEVS=$(python -c " + import json + with open('config/azure_devops_config.json', 'r') as f: + config = json.load(f) + devs = config.get('work_item_query', {}).get('default_developers', []) + print(','.join(devs)) + ") + echo "default_developers=${DEFAULT_DEVS}" >> $GITHUB_OUTPUT + + - name: Generate developer report + env: + AZURE_DEVOPS_ORG: ${{ secrets.AZURE_DEVOPS_ORG }} + AZURE_DEVOPS_PAT: ${{ secrets.AZURE_DEVOPS_PAT }} + run: | + # Determine which developers to use + if [ -n "${{ inputs.assigned_to }}" ]; then + # Manual trigger with specified developers + DEVELOPERS="${{ inputs.assigned_to }}" + else + # Use default developers from config + DEVELOPERS="${{ steps.config.outputs.default_developers }}" + fi + + # Build the command + CMD="python run.py --query-work-items \ + --start-date ${{ steps.dates.outputs.start_date }} \ + --end-date ${{ steps.dates.outputs.end_date }} \ + --optimized \ + --export-csv developer_report_${{ steps.dates.outputs.filename_suffix }}.csv" + + # Add assigned_to parameter + if [ -n "${DEVELOPERS}" ]; then + CMD="${CMD} --assigned-to \"${DEVELOPERS}\"" + fi + + # Execute the command + eval $CMD + + - name: Upload report artifacts + uses: actions/upload-artifact@v4 + with: + name: developer-report-${{ steps.dates.outputs.filename_suffix }} + path: | + developer_report_${{ steps.dates.outputs.filename_suffix }}.csv + developer_report_${{ steps.dates.outputs.filename_suffix }}_developer_summary.csv + retention-days: 90 + + - name: Create report summary + run: | + echo "## Developer Report Generated" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Date Range:** ${{ steps.dates.outputs.start_date }} to ${{ steps.dates.outputs.end_date }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Files Generated:**" >> $GITHUB_STEP_SUMMARY + echo "- \`developer_report_${{ steps.dates.outputs.filename_suffix }}.csv\` (Detailed)" >> $GITHUB_STEP_SUMMARY + echo "- \`developer_report_${{ steps.dates.outputs.filename_suffix }}_developer_summary.csv\` (Summary)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + # Show file sizes if they exist + if [ -f "developer_report_${{ steps.dates.outputs.filename_suffix }}.csv" ]; then + SIZE=$(du -h "developer_report_${{ steps.dates.outputs.filename_suffix }}.csv" | cut -f1) + echo "**Detailed Report Size:** ${SIZE}" >> $GITHUB_STEP_SUMMARY + fi + + if [ -f "developer_report_${{ steps.dates.outputs.filename_suffix }}_developer_summary.csv" ]; then + LINES=$(wc -l < "developer_report_${{ steps.dates.outputs.filename_suffix }}_developer_summary.csv") + DEVS=$((LINES - 1)) + echo "**Developers Analyzed:** ${DEVS}" >> $GITHUB_STEP_SUMMARY + fi diff --git a/OPTIMIZED_USAGE_EXAMPLES.md b/OPTIMIZED_USAGE_EXAMPLES.md index 42fe376..af0016f 100644 --- a/OPTIMIZED_USAGE_EXAMPLES.md +++ b/OPTIMIZED_USAGE_EXAMPLES.md @@ -22,7 +22,7 @@ python run.py --query-work-items --assigned-to "Luis Nocedal,Carlos Vazquez,Dieg python run.py --query-work-items --assigned-to "Luis Nocedal,Carlos Vazquez,Diego Lopez,Alejandro Valenzuela,Gerardo Melgoza,Hans Izarraraz,Osvaldo de Luna,Uriel Cortés,Emmanuel Pérez,Fernando Alcaraz,Damian Gaspar,Cristian Soria,Daniel Cayola,Ximena Segura, Andrés Escobedo, Alvaro Torres, Pablo Ruiz, Sebastián Rojas, Fernando Hernández" --start-date "2025-09-01" --end-date "2025-09-30" --optimized --export-csv "september_results.csv" -python run.py --query-work-items --assigned-to "Luis Nocedal,Carlos Vazquez,Diego Lopez,Alejandro Valenzuela,Gerardo Melgoza,Hans Izarraraz,Osvaldo de Luna,Uriel Cortés,Emmanuel Pérez,Fernando Alcaraz,Damian Gaspar,Cristian Soria,Daniel Cayola,Ximena Segura, Andrés Escobedo, Alvaro Torres, Pablo Ruiz, Sebastián Rojas, Fernando Hernández, Dan" --start-date "2025-09-01" --end-date "2025-09-30" --optimized --export-csv "september_results_final.csv" +python run.py --query-work-items --assigned-to "Luis Nocedal,Carlos Vazquez,Diego Lopez,Alejandro Valenzuela,Gerardo Melgoza,Hans Izarraraz,Osvaldo de Luna,Uriel Cortés,Emmanuel Pérez,Fernando Alcaraz,Damian Gaspar,Cristian Soria,Daniel Cayola,Ximena Segura, Andrés Escobedo, Alvaro Torres, Pablo Ruiz, Sebastián Rojas, Fernando Hernández, Daniel Reyes" --start-date "2025-09-01" --end-date "2025-09-30" --optimized --export-csv "september_results_final.csv" ### Basic Optimized Query ```bash diff --git a/README.md b/README.md new file mode 100644 index 0000000..8cba3a6 --- /dev/null +++ b/README.md @@ -0,0 +1,410 @@ +# Azure DevOps CLI Tool + +A powerful command-line utility for Azure DevOps analytics, featuring advanced developer scoring, work item querying, and performance metrics calculation. + +## Features + +- **Developer Scoring System**: Calculate comprehensive developer performance metrics +- **Advanced Work Item Querying**: Filter and analyze work items across projects +- **Efficiency Metrics**: Fair efficiency calculations with state transition tracking +- **Performance Optimized**: Batch processing with 70-95% speed improvements +- **CSV Export**: Detailed and summary reports for further analysis +- **Service Hook Management**: Create and manage Azure DevOps webhooks +- **Automated Monthly Reports**: GitHub Actions workflow for scheduled report generation + +## Installation + +### Prerequisites + +- Python 3.7+ +- Azure DevOps Personal Access Token (PAT) +- Access to Azure DevOps organization + +### Setup + +1. **Clone the repository** + ```bash + cd /path/to/project + ``` + +2. **Install dependencies** + ```bash + pip install -r requirements.txt + ``` + +3. **Configure environment variables** + + Create a `.env` file in the project root: + ```plaintext + AZURE_DEVOPS_ORG= + AZURE_DEVOPS_PAT= + ``` + + To create a PAT: + - Go to Azure DevOps → User Settings → Personal Access Tokens + - Create new token with `Work Items: Read` permission + - Copy the token to your `.env` file + +## Quick Start + +### List Projects +```bash +python run.py --list-projects +``` + +### Query Work Items with Developer Scores +```bash +python run.py --query-work-items \ + --assigned-to "Developer Name" \ + --start-date "2025-09-01" \ + --end-date "2025-09-30" \ + --export-csv "results.csv" +``` + +## Developer Score System + +The tool calculates a comprehensive **Overall Developer Score** based on four key metrics: + +### Score Components + +| Metric | Weight | Description | +|--------|--------|-------------| +| **Fair Efficiency** | 25% | Productivity relative to estimated time | +| **Delivery Score** | 50% | On-time delivery performance (60-130 points) | +| **Completion Rate** | 15% | Percentage of tasks completed | +| **On-Time Delivery** | 10% | Percentage completed within target date | + +### Fair Efficiency Calculation + +``` +Fair Efficiency = (Active Hours + Completion Bonus) / (Estimated Hours + Late Penalty) × 100% +``` + +**Key Features:** +- Active time capped at 1.2× estimate (prevents over-efficiency bias) +- 20% completion bonus for finished work items +- Paused/blocked time excluded from calculations +- Stack-based state transition tracking + +### Delivery Score + +**Early Delivery Bonuses:** +- Very early (≥7 days): 130 points + 1.0h bonus +- Early (≥3 days): 120 points + 0.5h bonus +- Slightly early (≥1 day): 110 points + 0.25h bonus +- On-time: 100 points + +**Late Delivery Penalties:** +- 1-3 days late: 90 points, 2h penalty mitigation +- 4-7 days late: 80 points, 4h penalty mitigation +- 8-14 days late: 70 points, 6h penalty mitigation +- 15+ days late: 60 points, 8h penalty mitigation + +### Score Interpretation + +| Overall Score | Level | Action | +|--------------|-------|--------| +| ≥86% | Excellent | Maintain performance | +| 65-85% | Good | Minor improvements | +| 55-64% | Fair | Attention needed | +| <55% | Low | Urgent action required | + +## Common Usage Examples + +### Basic Developer Query +```bash +python run.py --query-work-items \ + --assigned-to "John Doe" \ + --start-date "2025-10-01" \ + --end-date "2025-10-31" +``` + +### Multiple Developers with Export +```bash +python run.py --query-work-items \ + --assigned-to "Developer1,Developer2,Developer3" \ + --start-date "2025-09-01" \ + --end-date "2025-09-30" \ + --export-csv "september_results.csv" +``` + +### High-Performance Query (Optimized) +```bash +python run.py --query-work-items \ + --assigned-to "Developer Name" \ + --all-projects \ + --optimized \ + --max-workers 15 \ + --batch-size 200 \ + --export-csv "fast_results.csv" +``` + +### Specific Projects Only +```bash +python run.py --query-work-items \ + --project-names "ProjectA,ProjectB" \ + --assigned-to "Developer Name" \ + --export-csv "specific_projects.csv" +``` + +### Custom Scoring Weights +```bash +python run.py --query-work-items \ + --assigned-to "Developer Name" \ + --fair-efficiency-weight 0.3 \ + --delivery-score-weight 0.4 \ + --completion-rate-weight 0.2 \ + --on-time-delivery-weight 0.1 \ + --export-csv "custom_scoring.csv" +``` + +### Filter by Work Item Type and State +```bash +python run.py --query-work-items \ + --assigned-to "Developer Name" \ + --work-item-types "Task,Bug" \ + --states "Closed,Done" \ + --date-field "ClosedDate" +``` + +## Query Options + +### Filtering Options + +| Option | Description | Example | +|--------|-------------|---------| +| `--assigned-to` | Filter by assigned developers (comma-separated) | `"Dev1,Dev2"` | +| `--project-names` | Specific projects to query | `"ProjectA,ProjectB"` | +| `--all-projects` | Query all projects in organization | Flag only | +| `--work-item-types` | Filter by type | `"Task,Bug,User Story"` | +| `--states` | Filter by work item states | `"Closed,Done,Active"` | +| `--start-date` | Start date for filtering | `"2025-09-01"` | +| `--end-date` | End date for filtering | `"2025-09-30"` | +| `--date-field` | Date field to filter on | `"ClosedDate"` or `"CreatedDate"` | +| `--area-path` | Filter by area path | `"Project\\Area"` | +| `--iteration-path` | Filter by iteration | `"Sprint 1"` | + +### Performance Options + +| Option | Description | Speed Gain | +|--------|-------------|-----------| +| `--optimized` | Enable batch processing | 70-95% faster | +| `--ultra-optimized` | Bypass project discovery | 80-95% faster | +| `--max-workers` | Parallel worker count (default: 10) | Configurable | +| `--batch-size` | Items per API call (max: 200) | Default: 200 | +| `--no-parallel` | Disable parallel processing | N/A | + +### Scoring Configuration + +| Option | Description | Default | +|--------|-------------|---------| +| `--completion-bonus` | Completion bonus factor | 0.20 (20%) | +| `--max-efficiency-cap` | Maximum efficiency percentage | 150.0% | +| `--fair-efficiency-weight` | Fair efficiency weight | 0.25 (25%) | +| `--delivery-score-weight` | Delivery score weight | 0.50 (50%) | +| `--completion-rate-weight` | Completion rate weight | 0.15 (15%) | +| `--on-time-delivery-weight` | On-time delivery weight | 0.10 (10%) | + +### Export Options + +| Option | Description | +|--------|-------------| +| `--export-csv` | Export results to CSV file | +| `--no-efficiency` | Skip efficiency calculations (faster queries) | + +## Output Files + +The tool generates two types of CSV exports: + +### 1. Detailed Results CSV +Contains individual work item details: +- Work item ID, title, type, state +- Assigned developer +- Dates (created, closed, target) +- Time metrics (active hours, estimated hours) +- Efficiency metrics (fair efficiency, delivery score) +- State transition details + +### 2. Developer Summary CSV +Contains aggregated metrics per developer: +- Overall Developer Score +- Fair Efficiency percentage +- Average Delivery Score +- Completion Rate +- On-Time Delivery percentage +- Total Active Hours +- Total Estimated Hours +- Work item counts (total, completed, on-time) + +### Example Output + +``` +Developer: Fernando Alcaraz +┌─────────────────────────────────┐ +│ Overall Developer Score: 103.78%│ +│ Fair Efficiency: 109.43% │ +│ Delivery Score: 108.7 │ +│ Completion Rate: 100% │ +│ On-Time Delivery: 74% │ +│ Total Active Hours: 131.19 │ +│ Total Estimated Hours: 149 │ +│ Work Items: 50 total (50 done) │ +└─────────────────────────────────┘ +``` + +## Configuration + +### Configuration Files + +The tool uses multiple configuration sources (in order of precedence): + +1. **Command-line arguments** (highest priority) +2. **JSON configuration** (`config/azure_devops_config.json`) +3. **Environment variables** (`.env` file) +4. **Code defaults** (lowest priority) + +### Key Configuration Sections + +Edit `config/azure_devops_config.json` to customize: + +- **State Categories**: Define productive, blocked, and completion states +- **Business Hours**: Office hours and timezone settings +- **Scoring Parameters**: Efficiency caps, bonuses, and penalties +- **Work Item Types**: Default types to query +- **Smart Filtering**: Enable/disable intelligent project discovery + +## Advanced Features + +### Smart Project Discovery + +By default, the tool only queries projects where the specified developers have activity: +```bash +# Only queries projects with activity for these users +python run.py --query-work-items --assigned-to "User1,User2" +``` + +To query all projects: +```bash +python run.py --query-work-items --assigned-to "User1" --all-projects +``` + +### State Transition Tracking + +The tool uses a stack-based algorithm to accurately track: +- Active working time vs. blocked/paused time +- State transitions and their timestamps +- Reopened items with separate tracking +- Business hours enforcement + +### Service Hook Management + +Create webhooks for Azure DevOps events: +```bash +# Create a work item update webhook +python run.py --create-hook \ + --project-id "" \ + --event-type "workitem.updated" + +# List all subscriptions +python run.py --list-subscriptions --project-id "" + +# Create standard hooks (work items, builds, releases) +python run.py --create-standard-hooks --project-id "" +``` + +## Troubleshooting + +### Authentication Issues +- Verify your PAT has `Work Items: Read` permission +- Ensure `.env` file is in the project root +- Check organization name is correct (no URL, just the name) + +### Performance Issues +- Use `--optimized` flag for large datasets +- Reduce `--max-workers` if hitting API rate limits +- Use `--ultra-optimized` for maximum speed (bypasses smart filtering) + +### No Results Returned +- Verify date ranges match work item activity +- Check work item states match your query +- Ensure developers are assigned to work items in the date range +- Try `--all-projects` if smart filtering is too restrictive + +## Automated Monthly Reports (GitHub Actions) + +### Quick Setup + +The repository includes a GitHub Actions workflow that automatically generates developer reports on the 30th of each month. + +1. **Configure GitHub Secrets:** + - Go to **Settings** → **Environments** → **main** + - Add secrets: + - `AZURE_DEVOPS_ORG`: Your organization name + - `AZURE_DEVOPS_PAT`: Your Personal Access Token + +2. **Automatic Execution:** + - Runs on the 30th of each month at 23:00 UTC + - Generates reports for the 1st-30th of the current month + - Reports stored as artifacts for 90 days + +3. **Manual Execution:** + - Go to **Actions** → **Monthly Developer Report** + - Click **Run workflow** + - Specify custom date range and developers + +### Example Manual Run + +**Generate September 2025 report:** +```yaml +start_date: 2025-09-01 +end_date: 2025-09-30 +assigned_to: Developer1,Developer2 # Optional +``` + +**Output files:** +- `developer_report_2025-09-01_to_2025-09-30.csv` +- `developer_report_2025-09-01_to_2025-09-30_developer_summary.csv` + +For complete workflow documentation, see [`.github/workflows/README.md`](.github/workflows/README.md) + +## Documentation + +For more detailed information, see: + +- `.github/workflows/README.md` - GitHub Actions workflow setup and usage +- `documentation/README.md` - Comprehensive setup guide +- `documentation/WORK_ITEM_QUERYING_GUIDE.md` - Query system details +- `documentation/CONFIGURATION_USAGE.md` - Configuration system +- `GUIA_INTERPRETACION_METRICAS.md` - Metrics interpretation guide (Spanish) +- `OPTIMIZED_USAGE_EXAMPLES.md` - Performance optimization guide + +## Project Structure + +``` +Azure-devops-cli-tool/ +├── entry_points/ +│ └── main.py # CLI entry point +├── classes/ +│ ├── efficiency_calculator.py # Developer scoring logic +│ ├── WorkItemOperations.py # Query and analytics +│ ├── state_transition_stack.py # State tracking +│ └── ... +├── config/ +│ ├── azure_devops_config.json # Main configuration +│ └── config.py # Environment loader +├── documentation/ # Detailed documentation +├── run.py # CLI wrapper script +├── requirements.txt # Python dependencies +└── .env # Environment variables (create this) +``` + +## Support + +For issues or questions: +1. Check the documentation in the `documentation/` folder +2. Review example outputs in `Output files/` +3. Verify your configuration in `config/azure_devops_config.json` + +## License + +Internal tool for Inbest SF Automations diff --git a/config/azure_devops_config.json b/config/azure_devops_config.json index 7197f55..745e822 100644 --- a/config/azure_devops_config.json +++ b/config/azure_devops_config.json @@ -23,7 +23,14 @@ ], "date_field": "ClosedDate", "include_active_items": true, - "smart_filtering": true + "smart_filtering": true, + "default_developers": [ + "Luis Nocedal", + "Carlos Vazquez", + "Fernando Alcaraz", + "Rodrigo Mendoza", + "Jorge Hernandez" + ] }, "state_categories": { "assigned_states": [