팀 프로젝트를 포크해서 가져왔는데,
원본을 private으로 바꿔놓으면 가져올 수 없다고해서
새로운 레포지토리 생성해서 프로젝트를 가져왔습니다.
이슈까지 가져오는 코드이니
필요하신 분들은 참고해서 사용하세요 :)
초기에 한글 깨짐 이슈도 발생했었는데
그 부분까지 해결된 최종 코드입니다.
# 0) UTF-8 고정
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
[Console]::InputEncoding = [System.Text.UTF8Encoding]::new()
$ErrorActionPreference = "Stop"
# 1) 변수
$SRC = "원본 레포 이름" # 원본 레포
$DST = "대상 레포 이름" # 대상 레포
$AUTHOR = "내 Github 아이디" # 내 GitHub 아이디
# 2) 내 이슈 번호 수집 (내가 작성한 것만)
$srcMine = gh issue list -R $SRC --state all --author $AUTHOR --limit 2000 --json number | ConvertFrom-Json
$issueIds = $srcMine | ForEach-Object { $_.number }
"my issues: $($issueIds.Count) found"
if (-not $issueIds -or $issueIds.Count -eq 0) {
throw "No issues authored by $AUTHOR in $SRC"
}
# 3) 라벨/마일스톤 동기화는 원본과 동일
$srcLabels = (gh api "repos/$SRC/labels?per_page=100" --paginate) | ConvertFrom-Json
$dstLabels = (gh api "repos/$DST/labels?per_page=100" --paginate) | ConvertFrom-Json
$dstLabelNames = @{}; $dstLabels | % { $dstLabelNames[$_.name] = $true }
foreach ($lab in $srcLabels) {
if (-not $dstLabelNames.ContainsKey($lab.name)) {
gh api -X POST "repos/$DST/labels" -f name="$($lab.name)" -f color="$($lab.color)" | Out-Null
Start-Sleep -Milliseconds 60
}
}
$srcMsAll = (gh api "repos/$SRC/milestones?state=all&per_page=100" --paginate) | ConvertFrom-Json
foreach ($ms in $srcMsAll) {
$exists = (gh api "repos/$DST/milestones?state=all&per_page=100" --paginate) | ConvertFrom-Json |
Where-Object { $_.title -eq $ms.title } | Select-Object -First 1
if (-not $exists) {
gh api -X POST "repos/$DST/milestones" -f title="$($ms.title)" | Out-Null
Start-Sleep -Milliseconds 60
}
}
$dstMs = (gh api "repos/$DST/milestones?state=all&per_page=100" --paginate) | ConvertFrom-Json
$dstMsByTitle = @{}; $dstMs | % { $dstMsByTitle[$_.title] = $_ }
# 4) 마이그레이션 (내 이슈만)
foreach ($n in $issueIds) {
$marker = "migrated from $SRC#$n"
$dup = gh issue list -R $DST --state all --search "$marker" --json number | ConvertFrom-Json
if ($dup -and $dup.Count -gt 0) { "skip dup -> src #$n"; continue }
$i = gh issue view -R $SRC $n --json `
number,title,body,url,state,labels,assignees,milestone,comments,author `
| ConvertFrom-Json
if (-not $i) { "skip (cannot view) -> src #$n"; continue }
if ($i.author.login -ne $AUTHOR) { "skip not mine -> src #$($i.number)"; continue }
$origin = "[$marker | $($i.url)]`n`n"
$bodyTxt = if ($null -ne $i.body) { [string]$i.body } else { "" }
$bodyFull = @"
$origin$bodyTxt
"@
# (1) 이슈 생성
$newNum = gh api -X POST "repos/$DST/issues" `
-f title="$($i.title)" `
-f body="$bodyFull" `
--jq ".number"
"created -> dst #$newNum (from src #$($i.number))"
# (2) 마일스톤
if ($i.milestone -and $dstMsByTitle.ContainsKey($i.milestone.title)) {
gh api -X PATCH "repos/$DST/issues/$newNum" -f milestone="$($dstMsByTitle[$i.milestone.title].number)" | Out-Null
}
# (3) 라벨
foreach ($lab in $i.labels) {
gh api -X POST "repos/$DST/issues/$newNum/labels" -f "labels[]=$($lab.name)" | Out-Null
Start-Sleep -Milliseconds 30
}
# (4) 코멘트 (내가 단 코멘트만 가져오기)
foreach ($c in $i.comments) {
if ($c.author.login -ne $AUTHOR) { continue }
$cBody = if ($null -ne $c.body) { [string]$c.body } else { "" }
$cFull = @"
[from @$($c.author.login) | $($c.createdAt)]
$cBody
"@
gh api -X POST "repos/$DST/issues/$newNum/comments" -f body="$cFull" | Out-Null
Start-Sleep -Milliseconds 30
}
# (5) 상태
if ($i.state -eq "CLOSED") {
gh api -X PATCH "repos/$DST/issues/$newNum" -f state="closed" | Out-Null
}
"ok -> dst #$newNum"
Start-Sleep -Milliseconds 90
}
# 5) 결과 확인
gh issue list -R $DST --state all --limit 20