Intiial commit

Signed-off-by: Thomas Scott <tombomb122@noreply.localhost>
This commit is contained in:
Thomas Scott 2025-12-17 11:48:49 +00:00
parent 8161015b47
commit 9b4492cb97
1 changed files with 421 additions and 0 deletions

421
FIX_SUMMARY.md Normal file
View File

@ -0,0 +1,421 @@
# Bug Fixes Summary
## Overview
This document summarizes the recent bug fixes for bidirectional sync issues between Redmine and Gitea.
---
## Fix #1: Label to Field Mapping (Gitea → Redmine)
### Problem
When syncing from Gitea to Redmine:
- Gitea uses **labels** for tracker types ("bug", "feature") and priorities ("High Priority", etc.)
- Redmine uses **fields**: `tracker_id` and `priority_id`
- Previously, all Gitea issues were created in Redmine as "Bug" with "Normal" priority, regardless of labels
### Solution
Added reverse mapping to parse Gitea labels and convert them to Redmine field IDs:
**Tracker Mapping:**
```javascript
giteaToRedmine: {
"bug": 1, // Bug tracker
"feature": 2, // Feature tracker
"support": 3, // Support tracker
}
```
**Priority Mapping:**
```javascript
giteaToRedmine: {
"Low Priority": 1,
"Normal Priority": 2,
"High Priority": 3,
"Urgent": 4,
"Immediate": 5,
}
```
**New Utility Functions:**
- `extractTrackerFromLabels(labels)` - Scans labels for tracker types
- `extractPriorityFromLabels(labels)` - Scans labels for priority levels
- Falls back to defaults if no matching labels found
### Testing
```bash
# 1. Create issue in Gitea with labels:
# - "feature"
# - "High Priority"
# 2. Check Redmine:
# - Tracker: Feature
# - Priority: High
```
---
## Fix #2: Redmine Comments Not Syncing to Gitea
### Problem
- Adding notes/journals in Redmine didn't create comments in Gitea
- Gitea → Redmine comment sync worked fine
- Issue was one-directional
### Root Cause
The Redmine → Gitea sync only processed journals when creating NEW issues, not when updating existing ones.
### Solution
Modified the webhook handler to always process journals:
**Before:**
```javascript
if (giteaIssue) {
// Update issue
await GiteaAPI.updateIssue(...);
// ❌ Journals not processed here
} else {
// Create issue
await GiteaAPI.createIssue(...);
// ✅ Journals only processed for new issues
}
```
**After:**
```javascript
if (giteaIssue) {
// Update issue
await GiteaAPI.updateIssue(...);
// ✅ ALWAYS process journals
if (payload.journal) {
await SyncUtilities.processJournals(...);
}
}
```
### Improvements
1. **Better logging** for journal processing
2. **Safer author extraction** - handles both `journal.user.login` and `journal.author.login`
3. **Debug messages** to trace journal skipping decisions
4. **Change tracking** - field changes are included in Gitea comments
### Testing
```bash
# 1. Create issue in Redmine
# 2. Sync creates Gitea issue
# 3. Add note in Redmine with text: "This is a test comment"
# 4. Check Gitea issue - should see comment:
[Redmine Journal #14]
**admin** commented:
This is a test comment
**Changes:**
- status_id: 1 → 2
- due_date: (none) → 2025-12-19
```
---
## Fix #3: Date Format Issues (422 Errors)
### Problem
**Gitea → Redmine:**
- Gitea sends: `2025-12-19T00:00:00Z` (ISO 8601)
- Redmine expects: `2025-12-19` (date only)
- Result: 422 validation error
**Redmine → Gitea:**
- Redmine sends: `2025-12-19`
- Gitea expects: `2025-12-19T00:00:00Z` (ISO 8601)
- Previously could cause issues
### Solution
**For Gitea → Redmine:**
```javascript
// Extract date portion only
if (issue.due_date) {
const dueDate = new Date(issue.due_date);
if (!isNaN(dueDate.getTime())) {
issueData.due_date = dueDate.toISOString().split('T')[0];
// Result: "2025-12-19"
}
}
```
**For Redmine → Gitea:**
```javascript
// Convert to full ISO format
if (issue.due_date) {
const dueDate = new Date(issue.due_date);
if (!isNaN(dueDate.getTime())) {
issueData.due_date = dueDate.toISOString();
// Result: "2025-12-19T00:00:00.000Z"
}
}
```
**Safety Features:**
- Date validation before sending
- Try-catch blocks for invalid dates
- Warning logs for malformed dates
- Graceful fallback (omit field if invalid)
---
## Fix #4: Label Handling (422 Errors)
### Problem
**Redmine → Gitea:**
- Labels were included in issue create/update payload
- Gitea expects label IDs as numbers: `[1, 2, 3]`
- We were sending label objects: `[{name: "bug"}, {name: "feature"}]`
- Result: 422 validation error
### Solution
**Two-step process:**
1. **Create/update issue WITHOUT labels**
2. **Set labels separately using label IDs**
```javascript
// Step 1: Create/update issue
await GiteaAPI.updateIssue(owner, repo, number, {
title: "...",
body: "...",
state: "open",
// ❌ NO labels here
});
// Step 2: Set labels separately
await GiteaAPI.setIssueLabels(owner, repo, number, ["bug", "High Priority"]);
```
**Label ID Resolution:**
```javascript
static async setIssueLabels(owner, repo, number, labelNames) {
// Get all repository labels
const allLabels = await this.getLabels(owner, repo);
// Map names to IDs
const labelIds = [];
for (const labelName of labelNames) {
const label = allLabels.find(l => l.name === labelName);
if (label) {
labelIds.push(label.id);
}
}
// Send IDs to Gitea
if (labelIds.length > 0) {
await giteaClient.put(`/api/v1/repos/${owner}/${repo}/issues/${number}/labels`,
{ labels: labelIds }
);
}
}
```
---
## Fix #5: Enhanced Error Logging
### Problem
422 errors showed no details about what validation failed.
### Solution
Added detailed error logging for all 422 responses:
```javascript
catch (err) {
logger.error(`Sync failed: ${err.message}`);
// ✅ NEW: Show validation details
if (err.response?.status === 422) {
logger.error(`Validation error details: ${JSON.stringify(err.response.data)}`);
}
if (CONFIG.logging.verbose) {
logger.error(err.stack);
}
}
```
**Example Output:**
```
[ERROR] Gitea to Redmine sync failed: Request failed with status code 422
[ERROR] Validation error details: {"errors":["Due date is not a valid date"]}
```
This makes debugging much easier!
---
## Deployment
### Update Your Server
```bash
# 1. Pull latest changes
cd ~/redmine-gitea-sync
git pull
# 2. Restart PM2
pm2 restart redmine-gitea-sync
# 3. Watch logs to verify
pm2 logs redmine-gitea-sync
```
### Verify Fixes
**Test Label Mapping:**
```bash
# Create Gitea issue with labels "feature" and "High Priority"
# Check Redmine - should show Feature tracker with High priority
```
**Test Comment Sync:**
```bash
# Add note in Redmine
# Check Gitea - comment should appear
```
**Test Dates:**
```bash
# Create issue with due date in either platform
# Should sync without 422 errors
```
---
## Configuration
No configuration changes required. All fixes work automatically with existing settings.
### Optional: Enable Debug Logging
To see detailed sync information:
```javascript
// In ecosystem.config.cjs
env: {
LOG_LEVEL: 'debug',
LOG_VERBOSE: 'true',
}
```
Then:
```bash
pm2 restart redmine-gitea-sync --update-env
pm2 logs redmine-gitea-sync
```
---
## Known Limitations
### Tracker/Priority Mapping
- Only works for standard tracker IDs (1=Bug, 2=Feature, 3=Support)
- Custom Redmine trackers require manual mapping in code
- Custom priorities require manual mapping in code
### Comment Sync
- Only text notes sync (file attachments not yet supported)
- Very long comments may be truncated by platform limits
- Formatting differences between Markdown (Gitea) and Textile (Redmine)
### Labels
- Label colors are auto-generated (not synced)
- Category labels use prefix: `category:name`
- If label doesn't exist in Gitea, it's created automatically
---
## Troubleshooting
### Still Getting 422 Errors?
```bash
# Enable verbose logging
pm2 start ecosystem.config.cjs --env development
# Watch logs for validation details
pm2 logs redmine-gitea-sync
# Look for: "Validation error details: {...}"
```
### Comments Still Not Syncing?
```bash
# Check if journal has content
pm2 logs redmine-gitea-sync | grep "journal"
# Should see:
# "Synced Redmine journal #X to Gitea comment"
# If you see "Skipping journal - empty notes":
# - Add actual text to Redmine notes
# - Empty journals (only field changes) won't sync
```
### Labels Not Mapping?
```bash
# Verify label names match exactly:
# - "bug" (not "Bug" or "BUG")
# - "High Priority" (not "high priority" or "HighPriority")
# Check Gitea labels:
curl -H "Authorization: token TOKEN" \
https://gitea.example.com/api/v1/repos/OWNER/REPO/labels
```
---
## Version History
**v2.0.1** (Current)
- ✅ Fixed label to field mapping (Gitea → Redmine)
- ✅ Fixed Redmine comment sync to Gitea
- ✅ Fixed date format issues (both directions)
- ✅ Fixed label handling (Redmine → Gitea)
- ✅ Added detailed error logging
- ✅ Improved journal processing with better logging
**v2.0.0**
- Initial comprehensive rewrite
- PM2 support
- Basic bidirectional sync
- Label and milestone support
---
## Support
If you encounter issues after applying these fixes:
1. Check [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
2. Enable debug logging
3. Collect logs: `pm2 logs redmine-gitea-sync --lines 100`
4. Check server status: `curl http://localhost:3002/status`
5. Report with detailed logs and steps to reproduce