Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Ahmad Bustany <ahmadbustany06@gmail.com>
Omar Goher <omargoher59@gmail.com>
Rawan Essam <rawanessamwork@gmail.com>
Huda Amr <hudaamr2006@gmail.com>
AbdElrhman Mohamed <abdelrhman132006@gmail.com>
98 changes: 95 additions & 3 deletions doc/manual/en/60-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Billetsys includes a ticket import flow for bringing tickets into the system from external sources.

The first implementation focuses on CSV import. The import framework is designed so that additional adapters can be added later for systems such as Jira and Bugzilla without changing the core ticket creation workflow.
The first implementation focuses on CSV import, and Bugzilla CSV exports are also supported. The import framework is designed so that additional adapters can be added later for systems such as Jira without changing the core ticket creation workflow.

## Purpose

Expand Down Expand Up @@ -136,8 +136,100 @@ Not included yet:
* Live API connections to Jira or Bugzilla
* Credentials or background sync jobs

## Bugzilla

Tickets can be imported from a Bugzilla CSV export.

### Export

Bugzilla exports CSV from a bug search through `buglist.cgi?ctype=csv`. The CSV button on the results page adds `&human=1` to the link, which replaces the field names in the header with labels such as "Bug ID" and "Summary". Copy the link address of the CSV button, remove `&human=1`, and open that URL, so the header contains the field names. A file whose header contains labels was exported with `human=1` and cannot be imported. The file must use commas as the separator. This was checked with Bugzilla 5.0 and 5.2.

The default header is:

```
bug_id,"product","component","assigned_to","bug_status","resolution","short_desc","changeddate"
```

Extra columns can be requested with the `columnlist` parameter. Add `opendate` to preserve the creation date, and `bug_severity` to import enhancements as `Feature`. `columnlist` replaces the default columns instead of adding to them. Any default column that is not listed is dropped, including `short_desc`, so the full list must be given:

```
buglist.cgi?ctype=csv&columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,opendate,bug_severity,changeddate
```

Unknown column names are silently ignored, so `creation_ts` has no effect.

```
bug_id,"product","component","assigned_to","bug_status","resolution","short_desc","opendate","changeddate"
101,"Database","Replication","dev@example.com","CONFIRMED"," ---","Replica lags after restart","2026-03-02 09:14:00","2026-03-05 16:20:11"
```

There is one row per bug. An unresolved bug has `---` as its resolution. Bugzilla adds a leading space to any value that starts with `-`, `=`, `+` or `@`, so the resolution appears as ` ---`. Values are trimmed on import.

### Import

On the import page, select Bugzilla, choose the company and the entitlement, enter the time zone of the export (default UTC), and upload the file. The Bugzilla base URL is optional. The company and entitlement must exist in billetsys and apply to every row.

If the base URL is filled in, `external_issue_link` is set to the base URL + `show_bug.cgi?id=` + `bug_id`. If it is left empty, `external_issue_link` stays empty. The ticket can still be traced through `source_key` and the "Imported from Bugzilla bug #101" line in the initial message.

The time zone of the export is set in Bugzilla under Preferences, in the field "Timezone used to display dates and times". The default, "Site Default", is the time zone of the Bugzilla server.

### Field mapping

| billetsys field | Bugzilla source |
|---|---|
| `source_system` | Fixed value `bugzilla` |
| `source_key` | `bug_id` |
| `title` | `short_desc` |
| `status` | `bug_status` (see Status) |
| `created_at` | `opendate`, if exported, converted from the time zone chosen on the import page and reformatted to ISO `YYYY-MM-DDTHH:MM:SS` |
| `external_issue_link` | Base URL + `show_bug.cgi?id=` + `bug_id`, empty if no base URL is given |
| `initial_message` | Summary and other Bugzilla fields (see Initial message) |
| `category` | `Bug`, or `Feature` when `bug_severity` is `enhancement` |
| `requester_email` | Not mapped. The importing user is used |
| `company`, `entitlement` | Chosen on the import page |

### Status

Bugzilla statuses are configurable, and the CSV does not say whether a status is open or closed. A fresh Bugzilla uses `UNCONFIRMED`, `CONFIRMED`, `IN_PROGRESS`, `RESOLVED` and `VERIFIED`.

| Bugzilla status | billetsys status |
|---|---|
| `RESOLVED`, `VERIFIED`, `CLOSED` | `Closed` |
| Any other status | `Open` |

Only `Closed` is shown in the closed view.

### Initial message

The initial message contains the summary and the Bugzilla fields that have no place in a billetsys ticket. Empty values, and a resolution of `---`, are left out:

```
Summary: Replica lags after restart

Imported from Bugzilla bug #101
Product: Database
Component: Replication
Assignee: dev@example.com
Status: RESOLVED
Resolution: FIXED
```

### Limitations

* Descriptions, comments and attachments are not imported
* The reporter is not mapped, since it may not exist in billetsys
* Anonymous exports cut `assigned_to` down to the part before the `@`
* `resolution` and `assigned_to` are only kept in the initial message
* The close date is not imported. `changeddate` is the last modification time
* `opendate` has no time zone. It uses the time zone of the Bugzilla user who exported it
* Logged-in exports replace `\` with the fullwidth backslash `\` (U+FF3C). This is reversed on import
* Bugzilla cuts an export at `max_search_results` bugs (10000 by default) without a warning, and billetsys rejects uploads larger than 5 MB. Split larger migrations into several searches, for example one per product
* Bugs that the exporting user is not allowed to see are left out without a warning. Being an administrator is not enough
* Custom statuses that mean closed need to be changed before the import
* Duplicate detection uses `source_system` and `source_key`, as for CSV imports

## Future adapters

The import structure is designed so that new adapters can emit the same normalized ticket import rows used by the CSV source.
The import structure is designed so that new adapters can emit the same normalized ticket import rows used by the CSV source. The Bugzilla source works this way.

That means future support for Jira and Bugzilla can be added as new import sources while reusing the same validation, ticket creation, duplicate handling, and result reporting pipeline.
That means future support for Jira can be added as a new import source while reusing the same validation, ticket creation, duplicate handling, and result reporting pipeline.
1 change: 1 addition & 0 deletions doc/manual/en/97-acknowledgement.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Ahmad Bustany <ahmadbustany06@gmail.com>
Omar Goher <omargoher59@gmail.com>
Rawan Essam <rawanessamwork@gmail.com>
Huda Amr <hudaamr2006@gmail.com>
AbdElrhman Mohamed <abdelrhman132006@gmail.com>
```

## Committers
Expand Down
Loading