This commit is contained in:
2026-07-22 21:42:11 +02:00
parent 3c975a248e
commit 53a78f5d80
+211 -1
View File
@@ -1,2 +1,212 @@
# jotty_jira_sync
# Jira ↔ Jotty Sync
Bidirectional sync between [Jira](https://www.atlassian.com/software/jira) stories and [Jotty](https://github.com/fccview/jotty) task checklists.
## Features
- **Jira → Jotty**: Every Jira story becomes a checklist item in Jotty
- **Status sync**: Jira status maps to Jotty Kanban columns (To Do / In Progress / Completed / Paused)
- **Idempotent**: Running the script multiple times won't create duplicates — it reconciles state each run
- **Jira as source of truth**: Jira is the authoritative data source; Jotty items are updated/deleted to match
## Setup
### 1. Create a virtual environment and install dependencies
```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
### 2. Configure credentials
Copy the template and fill in your values:
```bash
cp sync_config.json.template sync_config.json
```
Or set environment variables (recommended — keep `.env` out of version control):
```bash
# .env file
JIRA_BASE_URL=https://jira.your-domain.com
JIRA_API_TOKEN=your_personal_access_token
PROJECT_KEY=PROJ
JOTTY_BASE_URL=https://jotty.your-domain.com
JOTTY_API_KEY=ck_your_api_key_here
```
### 3. Test the connection
```bash
source .venv/bin/activate
python jira_jotty_sync.py --direction=jira-to-jotty
```
## Usage
```bash
# Pull Jira stories into Jotty only
python jira_jotty_sync.py --direction=jira-to-jotty
# Push Jotty check/uncheck changes to Jira status only
python jira_jotty_sync.py --direction=jotty-to-jira
# Full two-way sync (default)
python jira_jotty_sync.py --direction=both
```
### CLI overrides
Override config values from the command line:
```bash
python jira_jotty_sync.py \
--jira-base https://jira.example.com \
--jira-token your_token \
--project PROJ \
--jotty-base https://jotty.example.com \
--jotty-key ck_your_key
```
## Status Mapping
### Jira → Jotty (Kanban columns)
| Jira Status | Jotty Column |
|-------------|--------------|
| NEW, TO DO, WAITING, READY | To Do |
| IN PROGRESS, TEST, PO REVIEW, READY FOR QA | In Progress |
| DONE, DEPLOYED, LIVE, TEST COMPLETED | Completed |
| IN QA, REJECTED | Paused |
### Jotty → Jira
| Jotty Column | Jira Status |
|--------------|-------------|
| To Do | TO DO |
| In Progress | IN PROGRESS |
| Completed | DONE |
| Paused | WAITING |
## How It Works
1. **Jira→Jotty sync**:
- Fetches all stories matching the JQL query from Jira
- Scans existing items in the Jotty checklist
- Updates status and text for matching items
- Creates new items for missing issues
- Deletes duplicate/orphaned items
2. **Jotty→Jira sync**:
- Reads current state of all checklist items
- Compares with actual Jira issue statuses
- Pushes status changes to Jira when they differ
## File Structure
```
jira_jotty_sync.py # Main sync script
requirements.txt # Python dependencies
sync_config.json.template # Configuration template
.env # Credentials (git-ignored)
sync_mapping.json # Auto-generated mapping file (Jira key → Jotty item index)
tests/ # Unit tests
```
## Notes
- The `sync_mapping.json` file is auto-managed — don't edit it manually
- `.env` and `sync_mapping.json` are git-ignored to protect credentials
- Uses the official [`jira`](https://pypi.org/project/jira/) Python library for Jira API access
- Personal Access Tokens (PAT) are used for self-hosted Jira authentication
**Option A — `.env` file (recommended):**
Copy and edit `.env.template`:
```bash
cp .env.template .env
```
Fill in your Jira base URL, username, API token, project key, and Jotty base URL + API key.
`.env` is gitignored so it won't be committed.
**Option B — `sync_config.json`:**
Copy and edit `sync_config.json.template`:
```bash
cp sync_config.json.template sync_config.json
```
Fill in your credentials there instead.
**Credential priority (highest → lowest):**
1. CLI flags (`--jira-base`, `--jira-user`, etc.)
2. Environment variables (`JIRA_BASE_URL`, `JOTTY_API_KEY`, …)
3. `.env` file (auto-loaded from the script's directory)
4. `sync_config.json`
| Variable | Description |
|---|---|
| `JIRA_BASE_URL` | e.g. `https://your-org.atlassian.net` |
| `JIRA_USERNAME` | Your Jira email / username |
| `JIRA_API_TOKEN` | Jira API token (from atlassian.com) |
| `PROJECT_KEY` | Jira project key, e.g. `PROJ` |
| `JOTTY_BASE_URL` | e.g. `https://jotty.your-domain.com` |
| `JOTTY_API_KEY` | Your Jotty API key (starts with `ck_`) |
### 3. Run the sync
```bash
# Full two-way sync
python jira_jotty_sync.py --direction both
# Pull new/updated stories from Jira into Jotty only
python jira_jotty_sync.py --direction jira-to-jotty
# Push Jotty check/uncheck changes to Jira only
python jira_jotty_sync.py --direction jotty-to-jira
```
### 4. CLI overrides
All config values can be overridden on the command line:
```bash
python jira_jotty_sync.py \
--jira-base https://mycompany.atlassian.net \
--jira-user you@company.com \
--project PROJ \
--direction jira-to-jotty
```
## Status Mapping
Edit `JIRA_TO_JOTTY_STATUS` and `JOTTY_TO_JIRA_STATUS` in the script to match your workflow.
| Jira Status | → Jotty Status |
|---|---|
| To Do | todo |
| In Progress | in_progress |
| Done | completed |
| In Review | review |
| Blocked | blocked |
## Mapping Persistence
The file `sync_mapping.json` stores the mapping between Jira issue keys and Jotty checklist item indices. It is automatically created on first run.
## Automation
Run periodically via cron:
```bash
# Every 15 minutes
*/15 * * * * cd /path/to/jotty_jira && python jira_jotty_sync.py --direction both >> sync.log 2>&1
```