All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 17m3s
- Introduced ADR-054 detailing the implementation of an automated sync worker to create Gitea issues from unresolved Bugsink errors. - Documented architecture, queue configuration, Redis schema, and implementation phases for the sync feature. - Added frontend testing summary for 2026-01-18, covering multiple sessions of API testing, fixes applied, and Bugsink error tracking status. - Included detailed API reference and common validation errors encountered during testing.
272 lines
8.1 KiB
Markdown
272 lines
8.1 KiB
Markdown
# Bugsink to Gitea Issue Synchronization
|
|
|
|
This document describes the automated workflow for syncing Bugsink error tracking issues to Gitea tickets.
|
|
|
|
## Overview
|
|
|
|
The sync system automatically creates Gitea issues from unresolved Bugsink errors, ensuring all application errors are tracked and assignable.
|
|
|
|
**Key Points:**
|
|
|
|
- Runs **only on test/staging server** (not production)
|
|
- Syncs **all 6 Bugsink projects** (including production errors)
|
|
- Creates Gitea issues with full error context
|
|
- Marks synced issues as resolved in Bugsink
|
|
- Uses Redis db 15 for sync state tracking
|
|
|
|
## Architecture
|
|
|
|
```
|
|
TEST/STAGING SERVER
|
|
┌─────────────────────────────────────────────────┐
|
|
│ │
|
|
│ BullMQ Queue ──▶ Sync Worker ──▶ Redis DB 15 │
|
|
│ (bugsink-sync) (15min) (sync state) │
|
|
│ │ │
|
|
└──────────────────────┼───────────────────────────┘
|
|
│
|
|
┌─────────────┴─────────────┐
|
|
▼ ▼
|
|
┌─────────┐ ┌─────────┐
|
|
│ Bugsink │ │ Gitea │
|
|
│ (read) │ │ (write) │
|
|
└─────────┘ └─────────┘
|
|
```
|
|
|
|
## Bugsink Projects
|
|
|
|
| Project Slug | Type | Environment | Label Mapping |
|
|
| --------------------------------- | -------- | ----------- | ----------------------------------- |
|
|
| flyer-crawler-backend | Backend | Production | bug:backend + env:production |
|
|
| flyer-crawler-backend-test | Backend | Test | bug:backend + env:test |
|
|
| flyer-crawler-frontend | Frontend | Production | bug:frontend + env:production |
|
|
| flyer-crawler-frontend-test | Frontend | Test | bug:frontend + env:test |
|
|
| flyer-crawler-infrastructure | Infra | Production | bug:infrastructure + env:production |
|
|
| flyer-crawler-test-infrastructure | Infra | Test | bug:infrastructure + env:test |
|
|
|
|
## Gitea Labels
|
|
|
|
| Label | Color | ID |
|
|
| ------------------ | ------------------ | --- |
|
|
| bug:frontend | #e11d48 (Red) | 8 |
|
|
| bug:backend | #ea580c (Orange) | 9 |
|
|
| bug:infrastructure | #7c3aed (Purple) | 10 |
|
|
| env:production | #dc2626 (Dark Red) | 11 |
|
|
| env:test | #2563eb (Blue) | 12 |
|
|
| env:development | #6b7280 (Gray) | 13 |
|
|
| source:bugsink | #10b981 (Green) | 14 |
|
|
|
|
## Environment Variables
|
|
|
|
Add these to **test environment only** (`deploy-to-test.yml`):
|
|
|
|
```bash
|
|
# Bugsink API
|
|
BUGSINK_URL=https://bugsink.projectium.com
|
|
BUGSINK_API_TOKEN=<from Bugsink Settings > API Keys>
|
|
|
|
# Gitea API
|
|
GITEA_URL=https://gitea.projectium.com
|
|
GITEA_API_TOKEN=<personal access token with repo scope>
|
|
GITEA_OWNER=torbo
|
|
GITEA_REPO=flyer-crawler.projectium.com
|
|
|
|
# Sync Control
|
|
BUGSINK_SYNC_ENABLED=true # Only set true in test env
|
|
BUGSINK_SYNC_INTERVAL=15 # Minutes between sync runs
|
|
```
|
|
|
|
## Gitea Secrets to Add
|
|
|
|
Add these secrets in Gitea repository settings (Settings > Secrets):
|
|
|
|
| Secret Name | Value | Environment |
|
|
| ---------------------- | ---------------------- | ----------- |
|
|
| `BUGSINK_API_TOKEN` | API token from Bugsink | Test only |
|
|
| `GITEA_SYNC_TOKEN` | Personal access token | Test only |
|
|
| `BUGSINK_SYNC_ENABLED` | `true` | Test only |
|
|
|
|
## Redis Configuration
|
|
|
|
| Database | Purpose |
|
|
| -------- | ------------------------ |
|
|
| 0 | BullMQ production queues |
|
|
| 1 | BullMQ test queues |
|
|
| 15 | Bugsink sync state |
|
|
|
|
**Key Pattern:**
|
|
|
|
```
|
|
bugsink:synced:{issue_uuid}
|
|
```
|
|
|
|
**Value (JSON):**
|
|
|
|
```json
|
|
{
|
|
"gitea_issue_number": 42,
|
|
"synced_at": "2026-01-17T10:30:00Z",
|
|
"project": "flyer-crawler-frontend-test",
|
|
"title": "[TypeError] t.map is not a function"
|
|
}
|
|
```
|
|
|
|
## Sync Workflow
|
|
|
|
1. **Trigger**: Every 15 minutes (or manual via admin API)
|
|
2. **Fetch**: List unresolved issues from all 6 Bugsink projects
|
|
3. **Check**: Skip issues already in Redis sync state
|
|
4. **Create**: Create Gitea issue with labels and full context
|
|
5. **Record**: Store sync mapping in Redis db 15
|
|
6. **Resolve**: Mark issue as resolved in Bugsink
|
|
|
|
## Issue Template
|
|
|
|
Created Gitea issues follow this format:
|
|
|
|
```markdown
|
|
## Error Details
|
|
|
|
| Field | Value |
|
|
| ------------ | ----------------------- |
|
|
| **Type** | TypeError |
|
|
| **Message** | t.map is not a function |
|
|
| **Platform** | javascript |
|
|
| **Level** | error |
|
|
|
|
## Occurrence Statistics
|
|
|
|
- **First Seen**: 2026-01-13 18:24:22 UTC
|
|
- **Last Seen**: 2026-01-16 05:03:02 UTC
|
|
- **Total Occurrences**: 4
|
|
|
|
## Request Context
|
|
|
|
- **URL**: GET https://flyer-crawler-test.projectium.com/
|
|
|
|
## Stacktrace
|
|
|
|
<details>
|
|
<summary>Click to expand</summary>
|
|
|
|
[Full stacktrace]
|
|
|
|
</details>
|
|
|
|
---
|
|
|
|
**Bugsink Issue**: https://bugsink.projectium.com/issues/{id}
|
|
**Project**: flyer-crawler-frontend-test
|
|
```
|
|
|
|
## Admin Endpoints
|
|
|
|
### Manual Sync Trigger
|
|
|
|
```bash
|
|
POST /api/admin/bugsink/sync
|
|
Authorization: Bearer <admin_jwt>
|
|
|
|
# Response
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"synced": 3,
|
|
"skipped": 12,
|
|
"failed": 0,
|
|
"duration_ms": 2340
|
|
}
|
|
}
|
|
```
|
|
|
|
### Sync Status
|
|
|
|
```bash
|
|
GET /api/admin/bugsink/sync/status
|
|
Authorization: Bearer <admin_jwt>
|
|
|
|
# Response
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"enabled": true,
|
|
"last_run": "2026-01-17T10:30:00Z",
|
|
"next_run": "2026-01-17T10:45:00Z",
|
|
"total_synced": 47
|
|
}
|
|
}
|
|
```
|
|
|
|
## Files to Create
|
|
|
|
| File | Purpose |
|
|
| -------------------------------------- | --------------------- |
|
|
| `src/services/bugsinkSync.server.ts` | Core sync logic |
|
|
| `src/services/bugsinkClient.server.ts` | Bugsink HTTP client |
|
|
| `src/services/giteaClient.server.ts` | Gitea HTTP client |
|
|
| `src/types/bugsink.ts` | TypeScript interfaces |
|
|
| `src/routes/admin/bugsink-sync.ts` | Admin endpoints |
|
|
|
|
## Files to Modify
|
|
|
|
| File | Changes |
|
|
| ------------------------------------- | ------------------------- |
|
|
| `src/services/queues.server.ts` | Add `bugsinkSyncQueue` |
|
|
| `src/services/workers.server.ts` | Add sync worker |
|
|
| `src/config/env.ts` | Add bugsink config schema |
|
|
| `.env.example` | Document new variables |
|
|
| `.gitea/workflows/deploy-to-test.yml` | Pass secrets |
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Core Infrastructure
|
|
|
|
- [ ] Add env vars to `env.ts` schema
|
|
- [ ] Create BugsinkClient service
|
|
- [ ] Create GiteaClient service
|
|
- [ ] Add Redis db 15 connection
|
|
|
|
### Phase 2: Sync Logic
|
|
|
|
- [ ] Create BugsinkSyncService
|
|
- [ ] Add bugsink-sync queue
|
|
- [ ] Add sync worker
|
|
- [ ] Create TypeScript types
|
|
|
|
### Phase 3: Integration
|
|
|
|
- [ ] Add admin endpoints
|
|
- [ ] Update deploy-to-test.yml
|
|
- [ ] Add Gitea secrets
|
|
- [ ] End-to-end testing
|
|
|
|
## Troubleshooting
|
|
|
|
### Sync not running
|
|
|
|
1. Check `BUGSINK_SYNC_ENABLED` is `true`
|
|
2. Verify worker is running: `GET /api/admin/workers/status`
|
|
3. Check Bull Board: `/api/admin/jobs`
|
|
|
|
### Duplicate issues created
|
|
|
|
1. Check Redis db 15 connectivity
|
|
2. Verify sync state keys exist: `redis-cli -n 15 KEYS "bugsink:*"`
|
|
|
|
### Issues not resolving in Bugsink
|
|
|
|
1. Verify `BUGSINK_API_TOKEN` has write permissions
|
|
2. Check worker logs for API errors
|
|
|
|
### Missing stacktrace in Gitea issue
|
|
|
|
1. Source maps may not be uploaded
|
|
2. Bugsink API may have returned partial data
|
|
3. Check worker logs for fetch errors
|
|
|
|
## Related Documentation
|
|
|
|
- [ADR-054: Bugsink-Gitea Sync](./adr/0054-bugsink-gitea-issue-sync.md)
|
|
- [ADR-006: Background Job Processing](./adr/0006-background-job-processing-and-task-queues.md)
|
|
- [ADR-015: Error Tracking](./adr/0015-application-performance-monitoring-and-error-tracking.md)
|