如何将问题从 Google Code 转移到 Phabricator

How to move issues from Google Code to Phabricator

Google 代码为 shutting down so I want to move my 2500 issues to Phabricator (hosted at Phoreplay).

虽然有 Github 和其他的移动程序,但我没有找到类似的 Phabricator 工具。

如何将问题从 Google Code 转移到 Phabricator?
只有问题,没有 wiki/code/downloads/etc.

注意:我使用 Phabricator 而不是 Github,因为它更适合 my requirements

如果您希望保留任务 ID 的初步说明

如果我们可以临时编辑 Maniphest 应用程序代码,则可以促进迁移项目,因此由于您无法控制安装,因此很难提供干净的解决方案来获得一致的 ID。因此,首先,您应该控制您的安装。

此类迁移代码已由 Blender 项目编写:here their repository 在导入时。

步骤

  1. 以 CSV 或 JSON 格式导出 Google 代码任务
  2. 运行 一个 Phabricator 脚本来导入它们,或者调用 API 管道

导出

Google 提供 some tools to perform the migration。这些工具包括一个 issues.py 脚本来解析 Google 代码上的问题。

这样,您就可以将问题转储为可行的格式,例如 JSON 来存储一组评论。

通过 API 导入(最适合最小的任务,无注释)

您可以使用 API 并通过管道 maniphest.createtask 调用。但这不是很方便,因为它不是添加评论、关闭问题等的最简单方法

通过脚本导入

这可能是最有趣的任务导入方式,也是提供最大灵活性的解决方案。

这里是我从 Blender 代码和我的一些内部代码起草的此类脚本的框架:

#!/usr/bin/env php
<?php

$root = dirname(dirname(__FILE__));
require_once $root . '/scripts/__init_script__.php';

/**
 * Represents a task importable into Phabricator
 */
class LegacyTask {
    private $id;
    private $title;
    //... other tasks properties, depending the Google Code fields

    public function importIntoPhabricator () {
        $projects = ......... // we need an array with one or more PHIDs, according what you created

        $task = ManiphestTask::initializeNewTask($reporter);
        $task->setTitle($title);
        $task->attachProjectPHIDs($projects);
        $task->setDescription($this->description);
        $task->setPriority($this->priority);
        $task->setOverrideID($this->id); //This is the method you want to borrow to the Blender migration code
        $task->save();

        //Initial transaction
        $changes = [
            ManiphestTransaction::TYPE_STATUS => ManiphestTaskStatus::STATUS_OPEN,
            PhabricatorTransactions::TYPE_VIEW_POLICY => 'public'
        ];
        self::applyTransactionsForChanges($task, $changes);

        //Closes task
        if ($this->closed) {
            $status = ... //ManiphestTaskStatus::STATUS_CLOSED_RESOLVED
            self::closeTask($task, $status);
        }

        //Project transaction
        self::associateTaskToProject($task, $projects);

        //Adds comments
        //...
    }

    static public function getTransactions ($changes) {
        $transactions = [];
        $template = new ManiphestTransaction();
        foreach ($changes as $type => $value) {
            $transaction = clone $template;
            $transaction->setTransactionType($type);
            if ($type == PhabricatorTransactions::TYPE_EDGE) {
                $transaction->setMetadataValue('edge:type', PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
            }
            $transaction->setNewValue($value);
            $transactions[] = $transaction;
        }

        return $transactions;
    }

    static public function applyTransactionsForChanges ($task, $changes) {
        $transactions = self::getTransactions($changes);
        self::applyTransactions($task, $transactions);
    }

    static public function applyTransactions ($task, $transactions) {
        $editor = id(new ManiphestTransactionEditor())
            ->setActor(self::getReporterUser())
            ->setContentSource(self::getContentSource())
            ->setContinueOnNoEffect(true)
            ->applyTransactions($task, $transactions);
    }

    static function associateTaskToProject($task, $projects) {
        $project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
        $transactions = [
            id(new ManiphestTransaction())
                ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
                ->setMetadataValue('edge:type', $project_type)
                ->setNewValue([
                    '=' => array_fuse($projects)
                ])
        ];
        self::applyTransactions($task, $transactions);
    }

    /**
     * Closes the task
     */
    static public function closeTask ($task, $status) {
        $changes = [
            ManiphestTransaction::TYPE_STATUS => $status
        ];
        self::applyTransactionsForChanges($task, $changes);
    }
}

已记录关闭状态 here

效果最好。

请您的核心开发人员和顶级记者创建一个帐户,尝试映射他们的用户,并为其他所有人将问题和评论归因于为迁移创建的机器人帐户。