From 53a78f5d804021fe2e8472f969e30c33bb919ab3 Mon Sep 17 00:00:00 2001 From: Rene Date: Wed, 22 Jul 2026 21:42:11 +0200 Subject: [PATCH] readme --- README.md | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 211 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f8af893..f860c96 100644 --- a/README.md +++ b/README.md @@ -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 +``` \ No newline at end of file