GitHub Magrations 내 이슈만 가져오기

혜빈·2025년 8월 24일

보충내용

목록 보기
37/38

GitHub Magrations 전체 내 이슈만 가져오기

팀 프로젝트를 포크해서 가져왔는데,
원본을 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
profile
최강 개발자를 꿈꾸는 병아리

0개의 댓글