Query-based Unified Issue Lightweight Linker: Sync GitHub issues to an on-premise Jira instance (stateless)
Project description
🪶 Quill (Query-based Unified Issue Lightweight Linker)
quill syncs GitHub issues and comments from multiple public repositories to an on-premise Jira instance. It is fully stateless — no local database or state file needed.
How the stateless design works
Each synced Jira issue gets the original GitHub issue URL stored in a Jira custom field (e.g., customfield_10200). On every sync run, quill queries Jira via JQL to discover which issues are already synced, then creates or updates as needed.
A content hash is embedded as an invisible footer in the Jira description (<!-- quill:sha256:... -->), enabling fast change detection without full-text diffing.
Features
- Multi-repository sync: Map multiple GitHub repos to specific Jira projects.
- Stateless: No local database — works natively in GitHub Actions without caching hacks.
- Incremental updates: SHA256 content hashes detect changes to title, body, labels, or state.
- State transitions: Optionally closes Jira issues when GitHub issues are closed.
- Comment sync: Comments are attributed (e.g., "@user commented on GitHub").
- Dry-run mode: Preview changes without writing to Jira.
- Minimal dependencies: PyGithub, python-jira, pydantic, pyyaml, rich, and stdlib argparse.
Installation
pixi install
This creates a Conda environment, installs all dependencies, and links the quill package in editable mode.
Configuration
quill is configured via a YAML file (see quill.yaml.example):
github:
token: ${GITHUB_TOKEN}
repos:
- owner: your-org
repo: your-repo
jira_project: CAS
sync_labels: true
sync_comments: true
issue_filter:
labels: ["bug", "enhancement"]
state: open
since: "2024-01-01"
jira:
server: https://jira.example.com
token: ${JIRA_PAT}
verify_ssl: true
default_issue_type: Task
github_link_field: customfield_10200 # custom field for GitHub URL
sync:
dry_run: false
batch_size: 50
Jira custom field setup
You need a custom field in Jira (type: URL or Text) to store the GitHub issue link. Set github_link_field in the config to the field's internal ID (e.g., customfield_10200). Ask your Jira admin if you don't have one.
Usage
# Generate a template config
pixi run quill init
# Test connectivity to GitHub and Jira
pixi run quill check
# Run synchronization
pixi run quill sync
# Sync a specific repo only
pixi run quill sync --repo your-org/your-repo
# Dry run — preview without writing
pixi run quill sync --dry-run
# Show synced issue counts (queries Jira)
pixi run quill status
Or using pixi tasks directly:
pixi run sync
pixi run check
pixi run status
pixi run test
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quill_sync-0.1.0.tar.gz.
File metadata
- Download URL: quill_sync-0.1.0.tar.gz
- Upload date:
- Size: 24.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e02b3e0b3ca1f67edf239dc3ebad96933826c129e72a4e50f01d72bcf8bd56ec
|
|
| MD5 |
3049c016015a8f5f8385b10daa561c28
|
|
| BLAKE2b-256 |
0623a7a2039f78fad9b64c0f103d2f85455cb7f8291e7f8c2f019c37a147203f
|
Provenance
The following attestation bundles were made for quill_sync-0.1.0.tar.gz:
Publisher:
publish.yml on r-xue/quill
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quill_sync-0.1.0.tar.gz -
Subject digest:
e02b3e0b3ca1f67edf239dc3ebad96933826c129e72a4e50f01d72bcf8bd56ec - Sigstore transparency entry: 2057214344
- Sigstore integration time:
-
Permalink:
r-xue/quill@076a2857a94c2083e60f30620f141452df02c8cd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/r-xue
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@076a2857a94c2083e60f30620f141452df02c8cd -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file quill_sync-0.1.0-py3-none-any.whl.
File metadata
- Download URL: quill_sync-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
364eb5862e49e5c4b8fcb629743720d3f6a400728b12d5bef9019bd9dae91b8d
|
|
| MD5 |
c0797f54f3c634ba1cc5e0d5972e4a3d
|
|
| BLAKE2b-256 |
335579b06ffe331f6854fc14b4568f9b4acc82433ce4cfe87e5f76e4a0fad914
|
Provenance
The following attestation bundles were made for quill_sync-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on r-xue/quill
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quill_sync-0.1.0-py3-none-any.whl -
Subject digest:
364eb5862e49e5c4b8fcb629743720d3f6a400728b12d5bef9019bd9dae91b8d - Sigstore transparency entry: 2057214746
- Sigstore integration time:
-
Permalink:
r-xue/quill@076a2857a94c2083e60f30620f141452df02c8cd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/r-xue
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@076a2857a94c2083e60f30620f141452df02c8cd -
Trigger Event:
workflow_dispatch
-
Statement type: