Skip to content

Instantly share code, notes, and snippets.

@alexander-zierhut
Last active February 1, 2022 23:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexander-zierhut/455be6b2ed737f9412b5a6faf6c151d8 to your computer and use it in GitHub Desktop.
Save alexander-zierhut/455be6b2ed737f9412b5a6faf6c151d8 to your computer and use it in GitHub Desktop.
Migrate Gitea Issues to Openproject
<?php
function getIssues() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://git.YOUR_URL_HERE/api/v1/repos/YOUR_ORG/YOUR_REPO/issues?state=open&type=issues&limit=1000&access_token=YOUR_GITEA_ACCESS_TOKEN');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
return $result;
}
function getCommentsOnIssue($issueId) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://git.YOUR_URL_HERE/api/v1/repos/YOUR_ORG/YOUR_REPO/issues/$issueId/comments?access_token=YOUR_GITEA_ACCESS_TOKEN");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
return $result;
}
function patchIssue($issueId, $body) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://git.YOUR_URL_HERE/api/v1/repos/YOUR_ORG/YOUR_REPO/issues/$issueId?access_token=YOUR_GITEA_ACCESS_TOKEN");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"state" => "closed",
"body" => $body
]));
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
return $result;
}
function op_request($req, $method = 'POST', $data = null) {
$ch = curl_init();
if(preg_match('~^/api/v3(.*)~', $req, $temp)) $req = $temp[1];
curl_setopt( $ch, CURLOPT_URL, 'https://openproject.YOUR_URL_HERE/api/v3' . $req );
curl_setopt( $ch, CURLOPT_USERPWD, "apikey:YOUR_OPEN_PROJECT_APIKEY" );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE );
if(isset($data)) {
$data = json_encode($data);
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $data);
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: '.strlen($data)
]);
}
$return = curl_exec($ch);
curl_close($ch);
return json_decode($return, true);
}
function parseDescription($description) {
preg_match_all('/#\d+/', $description, $matches);
foreach(($matches[0] ?? []) as $match) {
$id = substr($match, 1);
$url = "https://git.YOUR_URL_HERE/YOUR_ORG/YOUR_REPO/issues/$id";
$description = str_replace($match, "[G$id]($url)", $description);
}
return $description;
}
$issues = getIssues();
foreach($issues as $i => $issue) {
$issues[$i]["comments"] = getCommentsOnIssue($issue["number"]);
}
$projectId = 14;
foreach($issues as $issue) {
echo "Migrating issue $issue[number]\n";
// Parse the description
$description = "";
if(!empty($issue["body"])) $description .= "$issue[body]\n\n";
$description .= "Ticket source (archived): $issue[html_url]";
$description = parseDescription($description);
// RePost the ticket
$ticket = op_request("/api/v3/projects/$projectId/work_packages", data: [
"subject" => $issue["title"],
"description" => [
"format" => "markdown",
"raw" => $description
],
"scheduleManually" => false,
"startDate" => date("Y-m-d", strtotime($issue["created_at"])),
"dueDate" => null,
"estimatedTime" => null
]);
// RePost comments
foreach($issue["comments"] as $comment) {
$comment = op_request("/api/v3/work_packages/$ticket[id]/activities", data: [
"notify" => false,
"comment" => [
"raw" => parseDescription($comment["body"])
]
]);
}
$oldDescription = "Migrated to: https://openproject.YOUR_URL_HERE/projects/YOUR_PROJECT_NAME_OR_ID/work_packages/$ticket[id]";
if(!empty($issue["body"])) $oldDescription .= "\n\n$issue[body]";
patchIssue($issue["number"], $oldDescription);
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment