Important note: Trac was migrated to [howto/GitLab](howto/GitLab) in June 2020. See
[howto/gitlab](howto/gitlab#Migration) for the details. This is kept only for historical
reference.

# GitLab migration

GitLab was migrated from Trac in June 2020, after a few months of
testing. Tests were done first on a server called
`dip.torproject.org`, a reference to `salsa.debian.org`, the GitLab
server ran by the Debian project. We identified [some problems with
merge requests](https://gitlab.torproject.org/tpo/tpa/services/-/issues/32197) during the test so the server was reinstalled with
the "GitLab Omnibus" package on the current server, `gitlab-02` which
will enter production in the week of June 15th 2020.

## Why migrate?

We're hoping gitlab will be a good fit because:

 * Gitlab will allow us to collect our different engineering tools
   into a single application: Git repository handling, Wiki, Issue
   tracking, Code reviews, and project management tooling.
 * Gitlab is well-maintained, while Trac plugins are not well
   maintained and Trac itself hasn't seen a release for over a year
   (since 2019)
 * Gitlab will allow us to build a more modern approach to handling CI
   for our different projects. This is going to happen after the
   ticket and wiki migration.

(Note that we're only planning to install and use the freely licensed version
of gitlab.  There is an "enterprise" version with additional features, but we
prefer to use free software whenever possible.)

## Migrated content

The issues and wiki of the "Tor" project are migrated. There are no
other projects in Trac.

 * Trac wiki: <https://gitlab.torproject.org/legacy/trac>
 * Trac issues: <https://gitlab.torproject.org/legacy/trac/-/issues>

Trac issues that remain are really legacy issues, others issues have
been "moved" to the respective projects. @ahf, who did the migration,
created a [copy of the mapping](component-tickets) for those
looking for their old stuff.

All the tickets that were *not* moved to their respective projects
have been closed in the first week of july.

## Not migrated

We are *not* migrating away from Gitolite and Jenkins just yet. This
means those services are still fully operational and their equivalent
features in GitLab are *not* supported (namely Git hosting and
CI). Those services *might* eventually be migrated to GitLab, but
that's not part of the current migration plan. See [issue 36][] for
the followup on that.

[issue 36]: https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/36

Again, the canonical copy for source code hosted by git is:

 * `git-rw.torproject` - writable git repositories over SSH
 * <https://git.torproject.org/> - readonly clones
 * <https://gitweb.torproject.org/> - web interface

We also do not host "GitLab pages", the static site hosting provided
by GitLab.

The priority of those features would be:

 1. gitolite replacement and migration
 2. CI deployment, with people migrating their own job from Jenkinks
    and TPA shutting down Jenkins on a flag date
 3. GitLab pages replacement and migration from the current static
    site hosting system

Those are each large projects and will be undertaken at a later stage,
progressively.

## Feature equivalence

| Feature              | Trac           | GitLab                 | Comments                                                                        |
| -------              | ----           | ------                 | --------                                                                        |
| Ticket relations     | parent/child   | checklists             | checklists show up as "X of Y tasks completed"¹                                 |
| Milestones           | yes            | yes                    |                                                                                 |
| Estimates            | points/actual  | estimation/spending    | requires conversion from days to hours                                          |
| Private issues       | no             | yes                    |                                                                                 |
| Issue subscription   | RSS, email, ML | email                  | Trac sends email to trac-bugs                                                   |
| User projects        | no             | yes                    | if users can create projects                                                    |
| User registration    | optional       | disabled               | ²                                                                               |
| Search               | advanced       | basic                  | no support for custom queries in GitLab³                                        |
| Markup               | WikiCreole     | Markdown, GitHub-like  | ⁴                                                                               |
| IRC bot              | yes            | yes                    | zwiebelbot has to be patched, other bots to be deployed for notifications⁵      |
| Git hosting          | no, gitolite   | yes, builtin           | concerns about trusting GitLab with our code                                    |
| CI                   | no, Jenkins    | yes, builtin           | maybe in the future                                                             |
| Upstream maintenance | slow           | fast                   | Trac does not seem well maintained                                              |
| Wikis                | one big wiki   | per-project            | ⁶                                                                               |
| API                  | XML-RPC        | REST, multiple clients |                                                                                 |
| Javascript           | optional       | required               | Drag-and-drop boards seem not to work but the list of issues still can be used. |

Notes:

 1. Trac parent/child issue relationships have been converted into a
    simple comment at the beginnning of the ticket linking to the
    child/parent tickets. It was originally hoped to use the
    "checklists" features but this was not implemented for lack of time.

 2. User registration is perfectly possible in GitLab but since GitLab
    instances are frequently attacked by spammers, it is disabled
    until we find an alternative. See missing features below for
    details).

 3. GitLab, in particular, does not support inline searches, see
    Missing features below for details.

 4. The wiki and issue formatting markup is different. Whereas Trac
    uses [wiki formatting](https://trac.edgewall.org/wiki/WikiFormatting) inspired by old wikis like
    [MoinMoin](https://moinmo.in/), a subset of the somewhat standard [Wikicreole](http://www.wikicreole.org/)
    markup, GitLab uses [Markdown](https://en.wikipedia.org/wiki/Markdown), specifically their own [GitLab
    version of markdown](https://gitlab.com/help/user/markdown) inspired by GitHub's markdown
    extensions. The wiki and issues were automatically converted to
    Markdown, but when you file new issues, you will need to use
    Markdown, not Creole.

 5. specifically, zwiebelbot now knows about `foo#N` pointing to issue
    N in project `foo` in GitLab. We need to update (or replace) the
    `nsa` bot in `#tor-bots` to broadcast announcements to
    projects. This could be done with the [KGB](https://salsa.debian.org/kgb-team/kgb/-/wikis/home) bot for which we
    now have a [Puppet module](https://gitlab.com/shared-puppet-modules-group/kgb) so it could easily be deployed here

 6. because Trac does not allow users to create projects, we have
    historically used one gigantic project for everything, which means
    we had only one wiki. technically, Trac also supports one wiki per
    project, but because project creation requires an admin
    intervention, this never concretized.

## Ticket fields equivalence

| Trac            | GitLab                    | Comments                                                        |
| ----            | ------                    | --------                                                        |
| id              | id                        | keep the ticket id in legacy project, starts at 40000 in GitLab |
| Summary         | ?                         | unused?                                                         |
| Reporter        | Reporter                  |                                                                 |
| Description     | Body                      |                                                                 |
| Type            | Label                     | use templates to make sure those are filled                     |
| Milestone       | Milestone, Label          |                                                                 |
| Version         | Label                     |                                                                 |
| Keywords        | Label                     |                                                                 |
| Points, in days | /estimate, in hours       | requires conversion                                             |
| Actual points   | /spending                 |                                                                 |
| Sponsor         | Label                     |                                                                 |
| Priority        | Board, Label              | boards can sort issues instead of assigning arbitrary keywords  |
| Component       | Subproject, Label         |                                                                 |
| Severity        | Label                     | mark only blocker issues to resolve                             |
| Cc              | @people                   | paid plans also have multiple assignees                         |
| Parent issue    | #reference                | issue mentions and checklists                                   |
| Reviewer        | Label                     |                                                                 |
| Attachements    | Attachements, per comment |                                                                 |
| Status          | Label                     | Kanban boards panels                                            |

Notice how the `Label` field is used as a fallback when no equivalent
field exists.

## Missing features

GitLab does not provide one-to-one feature parity with Trac, but it
comes pretty close. It has issue tracking, wikis, milestones,
keywords, time estimates, and much more.

But one feature it is missing is the **advanced ticket query**
features of Trac. It's not possible to create "reports" in GitLab to
have pre-cooked issue listings. And it's especially not possible to
embed special searches in wiki pages the same way it is done in Trac.

We suggest people use the "dashboard" feature of GitLab instead. This
featuers follows the [Kanban][] development strategy which is
implemented in GitLab as [issue boards](https://docs.gitlab.com/ee/user/project/issue_board.html). It is also, of course,
possible to link so specific searches from the wiki, but not embed
those tickets in the output.

[Kanban]: https://en.wikipedia.org/wiki/Kanban_(development)

We do *not* have a **anonymous account** (AKA `cypherpunks`) for
now. GitLab will be in **closed registration** for now, with users
needing to request approval on a per-person basis for now. Eventually,
we're going to consider other options to work around this (human)
bottleneck.

## Interesting new features

 1. Using pull requests to your project repositories, and assigning
    reviewers on pull requests, rather than using `reviewer` and
    `needs_review` labels on issues. Issues can refer to pull requests
    and vice versa.

 2. Your team can work on using Gitlab boards for handling the
    different stages of issue handling. All the way from selection to
    finalization with code in a PR. You can have as many boards as you
    like: per subproject, per sponsor, per week, all of this is
    something we can experiment with.

 3. You can now use time estimation in Gitlab simply by adding a specially
    formatted comment in your issues/pull requests instead of using `points` and
    `actual_points`. See the [time tracking documentation](https://docs.gitlab.com/ee/user/project/time_tracking.html) for details

 4. Familiarize yourself with new interfaces such as the ["to do"
    dashboard](https://docs.gitlab.com/ee/user/todos.html) where you can see what needs your input since last
    visit

 5. Create email filters for tickets: Gitlab adds a lot more [email
    headers to each notification](https://docs.gitlab.com/ee/user/profile/notifications.html#filtering-email) you receive (if you want it via
    email), which for example allows you split notifications in your
    mail program into different directories.

    Bonus info: You will be able to reply via email to the notifications you
    receive from Gitlab, and Gitlab will put your responses into the system as
    notes on issues :-)

## bugs.torproject.org redirections

The <https://bugs.torproject.org> redirection now points at
GitLab. The following rules apply:

 1. **legacy tickets**: `bugs.torproject.org/N` redirects to
    `gitlab.torproject.org/legacy/trac/-/issues/N`
 2. **new issues**: `bugs.tpo/PROJECT/N` redirects to
    `gitlab.tpo/PROJECT/-/issues/N`
 3. **merge requests**: `bugs.tpo/PROJECT!N` redirects to
    `gitlab.tpo/PROJECT/-/merge_requests/N`
 4. **catch all**: `bugs.tpo/FOO` redirects to `gitlab.tpo/FOO`
 5. **ticket list**: a bare `bugs.tpo` redirects to
    `https://gitlab.torproject.org/tpo/-/issues`

It used to be that `bugs.tpo/N` would redirect to issue `N` the Trac
"tor" project. But unfortunately, there's no global "number space" for
issues in GitLab (or at least not a user-visible one), so `N` is not
distinct across projects. We therefore need the prefix to
disambiguate. 

We considered enforcing the `tpo` prefix there to shorten links, but
we decided against it because it would forbid pointers to
user-specific projects and would make it extremely hard to switch away
from the global `tpo` group if we ever decide to do that.

## Content organisation

Projects are all stored under the over-arching `tpo` group. This is
done this way to allow project managers to have an overview of all
projects going on at TPO. It also allows us to host other
organisations on our GitLab in a different namespace.

Under the `tpo` group, each team has its own subgroup and they have
autonomy under that group to manage accesses and projects.

## Permissions

Given the above Team/Group organization, users will be members in
gitlab for the groups/teams they belong to. 

Any projects that need to be shared between multiple groups should be
shared using the “Share Project” functionality.

There should be a limited number of members in the Tor Project group,
as these will have access to all subgroups and their
projects. Currently this is limited to Project Managers and Services
and Sysadmins.

A reminder of the GitLab [permission system](https://docs.gitlab.com/ee/user/permissions.html) and [types of users](https://about.gitlab.com/handbook/product/#permissions-in-gitlab):

 * Guests: anybody that may need to report issues on a project and/or
   make comments on an issue.
 * Reporter: they can also manage labels 
 * Developer: they can create branches, manage merge requests, force
   push to non-protected branches
 * Maintainer: edit projects, manage runners, edit comments, delete
   wiki pages.
 * Owner: we are setting this role for every member in the TPO
   team. They can also transfer projects to other name spaces, switch
   visilbity level, delete issues.

## Labels

At group level we have sponsor labels and state labels. The ones that
are used by the whole organization are in the `tpo` group. Each team
can decide which other labels they add for their projects.

 * Kanban columns
   * Icebox
   * Backlog
   * Next
   * Doing
   * Needs Review
 * Types of Issue
   * Defect
   * Enhancement
   * Task
 * Related to a project
   * Scalability
   * UX
 * Sponsors
   * Sponsor X
 * Keywords
   * Other possible keywords needed at group level.

Note that those labels are being worked on [ticket 4](https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/4). We also have
a lot more label than we would like ([ticket 3](https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/3)) which makes GitLab
hard to use. Because there are thousands of labels in some projects,
loading the label list can take a second or more on slower links, and
it's really hard to find the label you're looking for, which affects
usability -- and especially discoverability -- quite a bit.

ahf performed a major label cleanup operation on 2020-06-27, following
the specification in the [label cleanup](https://gitlab.torproject.org/ahf/label-cleanup/-/tree/main/) repository. It rewrote and
deleted labels in one batch in all projects. When the job was done,
[empty labels](https://gitlab.torproject.org/ahf/label-cleanup/-/blob/main/tpo/core/tor-delete.txt) were removed as well.

A [dump of the previous state](https://gitlab.torproject.org/ahf/label-cleanup/-/raw/main/tpo/core/tor-history.yaml) is available for historical
purposes.

## Project organisation

It is recommended that each team sets up a `team` project which can
welcome issues from outside contributors who might not otherwise know
where to file an issue.

That project is also where each team can have their own wiki. The Trac
wiki was migrated into the [legacy/trac](https://gitlab.torproject.org/legacy/trac) project but that content
will have to be manually migrated to the respective teams.

This organisation is still being discussed, see [issue 28](https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/28).

TODO: that issue is closed, stuff that is mentioned there might be
documented here or in the GitLab docs?

## Git repository migration

Migration from Gitolite is still being discussed, in [ticket 36](https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/36)
and is not part of this migration.

## What will break, and when will you fix it?

Most notably, we're going to have an interruption in the ability to open new
accounts and new tickets.  We _did not_ want to migrate without a solution
here; we'll try to have at least a stop-gap solution in place soon, and
something better in the future.  For now, we're planning for people that want
to get a new account please send a mail to <gitlab-admin@torproject.org>. We
hope to have something else in place once the migration is succesful.

We're not going to migrate long-unused accounts.

Some wiki pages that contained automated listings of tickets will stop
containing those lists: that's a trac feature that gitlab doesn't have. We'll
have to adjust our workflows to work around this. In some cases, we can use
gitlab milestone pages or projects that do not need a wiki page as a work
around.

## Actual migration process

The following repositories contain the source code that was used in
the migration:

 * <https://gitlab.torproject.org/ahf/gitlab-migration-tool>
 * <https://gitlab.torproject.org/ahf/gitlab-migration-utilities>
 * <https://gitlab.torproject.org/ahf/label-cleanup>
 * <https://gitlab.torproject.org/ahf/trac-migration>

The migration process was done by @ahf but was never clearly
documented (see [issue 21](https://gitlab.torproject.org/tpo/tpa/gitlab/-/issues/21)).

## Trac Archival

A copy of all Trac web pages were stored in the [Internet
Archive](http://archive.org/)'s [Wayback machine](http://web.archive.org/), thanks to [ArchiveBot](https://www.archiveteam.org/index.php?title=ArchiveBot), a tool
developed by [ArchiveTeam](https://www.archiveteam.org/), of which anarcat is somewhat a part of.

First, a list of tickets was created:

    seq 1 40000 | sed 's#^#https://trac.torproject.org/projects/tor/ticket/#'

This was uploaded to anarcat's pastebin (using [pubpaste](https://gitlab.com/anarcat/pubpaste)) and fed
into archivebot with:

    !ao < https://paste.anarc.at/publish/2020-06-17/trac.torproject.org-tickets-1-40000-final.txt
    !ao https://paste.anarc.at/publish/2020-06-17/trac.torproject.org-tickets-1-40000-final.txt

This tells ArchiveBot to crawl each ticket individually, and then
archive the list itself as well.

Simultaneously, a full crawl of the entire site (and first level
outgoing links) was started, with:

    !a https://trac.torproject.org --explain "migrated to gitlab, readonly" --delay 500

A list of excludes was added to ignore traps and infinite loops:

    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/query.*[?&]order=(?!priority)
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/query.*[&?]desc=1
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://gitweb\.torproject\.org/
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/timeline\?
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/query\?status=!closed&keywords=
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/query\?status=!closed&(version|reporter|owner|cc)=
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/query\?(.*&)?(reporter|priority|component|severity|cc|owner|version)=
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://cdn\.media\.ccc\.de/
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://www\.redditstatic\.com/desktop2x/
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://trac\.torproject\.org/projects/tor/report/\d+.*[?&]sort=
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://support\.stripe\.com/
    !ig bpu6j3ucrv87g4aix1zdrhb6k  ^https?://cdn\.cms-twdigitalassets\.com/
    !ig bpu6j3ucrv87g4aix1zdrhb6k  ^https?://cypherpunks\:writecode@trac\.torproject\.org/
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://login\.blockchain\.com/
    !ig bpu6j3ucrv87g4aix1zdrhb6k ^https?://dnsprivacy\.org/

The crawl was slowed down with a 500-1000ms delay to avoid hammering the server:

    !d bpu6j3ucrv87g4aix1zdrhb6k 500 1000

The results will be accessible in the wayback machine a few days after
the crawl. Another crawl was performed back in 2019, so the known full
archives of Trac are as follows:

 * [june 2019 ticket crawl](https://archive.fart.website/archivebot/viewer/job/5vytc): 6h30, 29892 files, 1.9 GiB
 * [june 2020 ticket crawl](https://archive.fart.website/archivebot/viewer/job/c4xu3): 4h30, 33582 files, 1.9GiB
 * [june 2019 and 2020 full crawls](https://archive.fart.website/archivebot/viewer/job/bpu6j): 5 days, 7h30, 732488 files,
   105.4 GiB; 5 days, 16h10, 837100 files, 137.6 GiB.

This information can be extracted back again from the `*-meta.warc.gz`
(text) files in the above URLs. This was done as part of [ticket
40003](https://gitlab.torproject.org/tpo/tpa/services/-/issues/40003). There has also been other, independent, crawls of Trac,
which are partly visible [in the viewer](https://archive.fart.website/archivebot/viewer/?q=trac.torproject.org).

## History

 * lost in the mists of time: migration from Bugzilla to Flyspray (40
   tickets)
 * 2010-04-23: [migration from Flyspray to Trac completed][] (last
   Flyspray ticket is [1393][], first Trac ticket is [2000][])
 * 2016-11-29: [first request to setup a GitLab server][]
 * ~2017: oniongit.eu (warning: squatted domain) deployed to test
   GitLab with the network team, considered as gitlab.torproject.net
   but ultimately [abandoned][]
 * 2019-02-28: `gitlab-01` AKA dip.torproject.org test server setup
   ([issue 29400][]), following the [Brussels meeting][]
 * 2019-07-17: GitLab discussed again at the [Stockholm meeting][]
 * 2019-07-29: Formal proposal to deploy GitLab [sent to
   tor-project][], no objection
 * 2020-03-05: GitLab migrated from `gitlab-01` (AKA "dip") to
   `gitlab-02` using the Omnibus package
 * 2020-04-27: `gitlab-01` retired
 * 2020-06-13 19:00UTC: [Trac readonly][]
 * 2020-06-13 02:25UTC: Trac tickets migrated (32401 tickets, last
   ticket id is [34451][], first GitLab legacy project ticket id is
   40000)
 * 2020-06-14 21:22UTC: Trac wiki migrated
 * 2020-06-15 18:30UTC: bugs.torproject.org redirects to gitlab
 * 2020-06-16 02:15UTC: GitLab launch announced to tor-internal
 * 2020-06-17 12:33UTC: Archivebot starts crawling all tickets of, and
   the entire Trac website
 * 2020-06-23: Archivebot completes the full Trac crawl, Trac is fully
   archived on the Internet Archive

[migration from Flyspray to Trac completed]: https://lists.torproject.org/pipermail/tor-dev/2010-April/000183.html
[1393]: https://bugs.torproject.org/1393
[2000]: https://bugs.torproject.org/2000
[first request to setup a GitLab server]: https://gitlab.torproject.org/tpo/tpa/services/-/issues/20821
[abandoned]: https://gitlab.torproject.org/tpo/tpa/services/-/issues/21840
[issue 29400]: https://gitlab.torproject.org/tpo/tpa/services/-/issues/29400
[Brussels meeting]: https://trac.torproject.org/projects/tor/wiki/org/meetings/2019BrusselsAdminTeamMinutes
[Stockholm meeting]: https://gitlab.torproject.org/legacy/trac/-/wikis/org/meetings/2019Stockholm/Notes/InternalTooling
[sent to tor-project]: https://lists.torproject.org/pipermail/tor-project/2019-July/002407.html
[Trac readonly]: https://lists.torproject.org/pipermail/tor-project/2020-June/002872.html
[34451]: https://bugs.torproject.org/34451

# Commandline access

We use [cartman](https://github.com/tamentis/cartman/), a "commandline trac client" which "allows you to
create and manage your Trac tickets from the command-line, without the
need to setup physical access to the Trac installation/database".

Install:

    virtualenv --python=python3 --system-site-packages ~/.virtualenvs/cartman
    ~/.virtualenvs/cartman/bin/pip install cartman
    alias cm=~/.virtualenvs/cartman/bin/cm

Config:

    [trac]
    base_url = https://trac.torproject.org/projects/tor
    username = anarcat
    password = ....
    auth_type = basic

The password can be ommitted and passed through the environment
instead with [this patch](https://github.com/tamentis/cartman/pull/30).

Template:

    To: anarcat
    Cc: 
    Milestone: 
    Component: Internal Services/Tor Sysadmin Team
    Priority: Medium
    Type: defect
    Keywords: 
    Version: 
    Subject: test

    test

Running:

    TRAC_PASSWORD=$(pass trac.torproject.org) cm new

# Other documentation

There's very little documentation on our Trac instance out there. This
page was originally created to quickly jot down notes on how to
batch-create tickets. There's also a [Trac page in the Tor Trac
wiki](https://gitlab.torproject.org/legacy/trac/-/wikis/org/operations/services/trac) and the [upstream documentation](https://trac.edgewall.org/).
