Keelcroft / GitLab Issues Sync for Jira
GitLab Issues Sync for Jira
Keep a Jira issue and a GitLab issue in step, and prove it.Published
Available on Atlassian Marketplace. Approved and published on 16 October 2026.
Start the standard 30-day Marketplace trial. Paid via Atlassian; use the Marketplace pricing calculator for your Jira site size.
Start standard 30-day free trial · Get setup help for your first issue pair
What it does
Release information dated 30 October 2026, effective upon publication.
A Jira project administrator connects one Jira project to one GitLab project and chooses which fields travel in which direction. Link existing issues, enable qualifying automatic creation, or preview and import an existing backlog. The sync engine reads both sides, applies the configured mappings and conflict policy, then reads back destination values to verify the result.
- Title, descriptions, labels and status: select either or both directions for supported fields. Formatted descriptions and new comments convert between Jira rich text and GitLab Markdown, including headings, emphasis, links, code, lists, task lists, quotes, tables and alerts. Images become links, not embedded Jira media; not every GitLab-specific extension or image-sizing instruction is preserved. New connections default description sync to Both; existing description settings are retained.
- Priority and custom mappings: map Jira priorities to explicit GitLab labels, and components or supported custom fields to label-prefix groups. Managed labels are kept separate from ordinary labels. This is not a native GitLab priority field or arbitrary custom-field support; custom pairs share one conflict group.
- Milestones, dates and weight: map Jira fix versions to an existing project/group milestone, Jira due/custom dates to GitLab due/start dates, and supported numeric fields to weight. No milestone is created; a GitLab issue has one milestone. Start date requires GitLab 19.1 or later; weight requires GitLab Premium or Ultimate. Unsupported values and missing milestones are refused before writing.
- Explicit assignee maps: pair Jira account IDs with GitLab usernames; the app resolves GitLab numeric IDs for assignment. Additional GitLab assignees are preserved, and an unassignment that would remove them is refused.
- Reconciliation: inspect linked pairs, last verification, conflicts and failures; use read-only Preview to inspect the next decision or Replay to request an actual sync. Check connection reads project/webhook health without creating an issue. A separate setup check creates a disposable GitLab issue, reads it back and attempts to remove it.
Optional workflow labels
The default status map translates Jira statuses to GitLab's binary opened/closed state; reverse mapping chooses the first configured Jira status for that state. For more detail, opt in to a managed label prefix and up to 30 explicit Jira-status/GitLab-label/binary-state rules. These labels are not GitLab's native custom statuses. Missing, multiple, unknown or state-inconsistent workflow labels stop transfer instead of guessing.
Adding, changing or removing workflow rules, including their status direction, requires Pause sync, no saved webhook and zero linked pairs. Existing baselines are not automatically migrated. Automatic GitLab creation needs an Open rule; Jira's initial workflow status must be mapped when exporting status.
Creation and backlog import
- Optional automatic creation both ways uses new-issue or explicit trigger-label rules; a chosen trigger label can qualify older issues. Configure a project-valid default Jira issue type, up to ten first-match label/type rules, Jira JQL and a common exclude label. Selection filters do not stop already linked pairs from syncing.
- Backlog import works both ways with preview, open/all scope, label filtering, limits of 25/100/250/500, progress, failure reporting and cancellation. Enabling sync alone does not import the backlog.
- Pending imports recheck source existence and selection rules. Dispatch complete is not proof that every counterpart was created and verified. Cancel stops pending creation, not writes already in flight; it does not delete created issues.
- Imports do not copy historical comments or files. Preview is a changing selection, not a reservation or proof of equivalent destination permissions.
Optional new comments and files
- New comments after linking can copy either or both ways with author attribution and a source marker. Restricted/internal Jira comments and GitLab internal/system notes are excluded. Edits and deletions are not mirrored.
- Reads are bounded to five pages of 100 comments/notes per side, with ten copies per direction/pass. Comments over 30,000 source characters are visibly shortened; incomplete histories pause copying.
- Jira attachments and GitLab uploads referenced in notes can copy after linking, up to 10 MiB/file and three files per direction/pass. Downloads are buffered before size checking, not streaming-memory-bounded or malware-scanned.
- New connections default comment and file directions to Both; missing legacy settings remain Off unless explicitly enabled. Known upload outcomes resume attribution work without reupload; unknown outcomes require reconciliation. Durable GitLab recovery references contain an upload secret and encoded filename; see Privacy.
Verification, preview and missed-change recovery
Field writes are followed by a separate destination read and value comparison. The reconciliation view records disagreement and policy decisions. Jobs are serialized per connection and terminal event records suppress repeated processing; this is not an atomic transaction across platforms or a universal exactly-once guarantee.
Read-only pair Preview returns field names, conflict/override decisions and mapping-problem codes, not field values or document content. It changes no issue, baseline, storage record or queue. Preview is not Replay, a permissions audit, or a prediction of comment/file counts.
A scheduled recovery sweep runs on a five-minute schedule and requeues existing linked pairs for the ordinary engine, including enabled comment/file adapters. Each invocation has at most ten pair slots, five per connection, and a 20-second budget for starting new work; an outstanding request can take longer. Persistent cursors help work resume. Queue delays, API limits and installation size still apply: this is not a five-minute completion promise or SLA. Recovery does not discover unlinked issues missed by webhooks; use backlog import for those.
Privacy and operational boundaries
- Confidential GitLab issues are blocked from export by default, including existing linked pairs. A project administrator can explicitly opt in after a warning: Jira issue security is not set and source audiences are not preserved. Public destination projects can expose copies. The safeguard is not a write ACL; concurrent changes can race, and a direct write/create can occur before response/read-back refusal. It does not erase existing copies.
- Pause and unlink are not deletion. Pause saves disabled state before attempting webhook cleanup and retains the token, settings, links and history. Failed cleanup is reported for retry/manual removal. Confirmed unlink removes pair/index entries, not either issue or copied content. Work already in flight may finish. There is no general disconnect/delete-connection control.
- No issue-deletion mirroring. A missing record leaves the surviving issue alone. The separate setup check may delete only its disposable test issue; if deletion is refused it closes it and reports that result.
- Only plain issues. Tasks, incidents, test cases, requirements and OKRs of other work-item types are not synced. GitLab has no issue-deletion webhook; a missing record is detected on a later read, sync or replay.
- Labels must be expressible. Unsupported plain labels are reported, not silently rewritten. GitLab's comma-separated label write format cannot represent a label containing a comma.
- Direct Forge processing. There is no Keelcroft-hosted relay. Egress to GitLab means the app is not eligible for the Runs on Atlassian badge.
Verification evidence and limits
Receiving-side GitLab.com live checks cover field, comment and import round trips; earlier live checks also verified file bytes both ways, creation, assignee mapping and restricted/internal-note exclusions. Automated tests cover additional mapping, workflow, privacy and recovery paths. Those are different kinds of evidence: they do not establish self-managed GitLab compatibility, separate-user permission equivalence, load capacity, scheduled recovery timing or every failure scenario. No competitor head-to-head or overall-best claim is made.
What you need to connect
- A GitLab access token with the
apiscope, held by a user with at least the Maintainer role on the project. Maintainer is what GitLab requires to manage a project's webhooks, so a token withapibut a lower role will read and write issues and still fail the webhook step. - On GitLab.com Free, use a personal access token; project access tokens require Premium or Ultimate. Token type does not replace the required scope and project permissions.
- Jira project administrator rights on the project you connect.
- A self-managed destination requires your Atlassian organisation admin to approve its host through customer-managed egress controls. This configuration path is not a claim of completed self-managed live testing; contact support before relying on it.
Support
Email support@keelcroft.com. Security reports: same address, subject line “Security”.
GitLab is a trademark of GitLab Inc. Keelcroft is an independent publisher and is not affiliated with, endorsed by, or sponsored by GitLab or Atlassian.