Git

Gitlab 에서 Github 로의 마이그레이션 ( MR to PR )

Seung-o 2023. 11. 11. 19:52

개요

회사에서 Git 저장소를 Gitlab에서 Github로 이전하게 되었다. 마이그레이션 방법과 유의점에 대해 적어보고자 한다. 

 

시작하기 전, 본 마이그레이션 방법은 큰 조직에는 그리 유용하지 않을 수 있다는 점을 미리 말한다. 지속적으로 MR 이 올라오고 이에 따라 배포가 이루어져야만 하는 조직에서는 Gitlab에서의 계속되는 변화를 Continuos 하게 Github로 옮기기 위해 미러링 등의 방법을 고려해야 한다. 

 

필자의 조직( 백엔드팀 )은 5명 내외의 크지 않은 조직이기에, 팀원들에게 양해를 구하고 잠시 Gitlab으로 MR 올리는 것을 중지해달라는 양해를 구하고 마이그레이션을 진행하였다.

 

 

Repsoitory 마이그레이션

 

Repository 마이그레이션은 간단하게 진행하였다. 현재는 로컬 저장소가 Gitlab에 연결되어 있다는 가정 하에, 아래 과정을 순서대로 따르면 된다.

 

1. Gitlab 원격 저장소에서 모든 브랜치를 로컬로 가져온다.

$ git fetch -all
$ git pull -all

 

2. Github에 Repository를 생성한다.

 

이 때, public / private 을 잘 구분하여 생성해주면 된다. 생성 후에는 저장소의 원격 주소가 화면에 나타난다. 

 

3. 로컬 저장소의 원격 주소를 앞선 Github의 원격 주소로 변경한다.

$ git remote set-url git@github.com:Seung-o/migrated.git

 

4. 로컬 저장소의 모든 브랜치를 원격 저장소로 push 한다.

$ git push --all origin

 

5. Github의 원격 저장소에 접속하여, 마이그레이션이 성공적으로 반영되었는지 확인한다. 이 때, 모든 커밋과 각 개인의 기여도 ( 이메일 기준 ) 역시도 모두 반영된다. 

 

MR 마이그레이션

 

올라와있는 MR들을 PR로 옮기는 작업 역시도 필요하다. 이를 위해 node-gitlab-2-github 라이브러리를 사용하였다. 이 라이브러리를 사용했을 때, 개인적으로 느낀 장/단점은 아래와 같다.

 

장점

- MR에서 PR로의 마이그레이션이 잘 이루어진다. 조금 더 구체적으로는 호환을 많이 신경썼다. 

  - 원격 저장소에 존재하는 브랜치에 대한 MR은 PR로, 존재하지 않는 브랜치에 대한 MR은 Issue로 매칭시킨다.

- 유저 맵핑도 가능하다. Gitlab에서의 A 이름을 가진 유저가 Github에서 B 이름을 가졌다면, 두 계정을 매칭시킬 수 있다.

- MR 뿐만 아니라, 사용하고 있던 태그, 마일스톤, 이슈도 모두 옮겨준다.

 

단점

- MR이 많으면 속도가 현저히 느리다. 

  - Github API 중 PR을 생성하는 API를 사용하는데, 이것이 속도제한이 있다. 단시간에 너무 많은 요청을 보내면, Abused 처리가 되고 이 라이브러리는 이 경우, 1000초를 기다렸다가 다시 요청하는 프로세스를 지닌다. 

  - 만약 1000초를 기다렸는데도 Abused가 풀리지 않았다면 대기시간이 무한정 길어지는 것이다. 

  - 필자는 3000초까지도 기다리는 로그를 보았다..

  - 필자는 MR 600개 정도에 대해 18 시간 정도 소요되었다. 

- PR이 Merged가 아닌 Closed로 이전된다. 

 

본인의 상황에 따라 단점에 감안할만하다고 한다면, 사용하는 것도 좋은 선택이 된다.

 

아래는 라이브러리 사용 방법이다. 

 

1. 라이브러리 다운로드

git clone https://github.com/piceaTech/node-gitlab-2-github.git
cd node-gitlab-2-github
npm install

 

2. 다운받은 라이브러리로 들어간 후, 세팅 파일을 설정한다.

cp sample_settings.ts settings.ts
vim settings.ts

 

vim이 익숙하지 않다면, 본인이 익숙한 편집기에서 진행하면 된다. 필자는 vscode IDE에서 세팅 파일 설정을 진행하였다.

 

import Settings from './src/settings';

export default {
  gitlab: {
    // url: 'https://gitlab.mycompany.com',
    token: '{{gitlab private token}}', // 필수
    projectId: 0, // 필수
    listArchivedProjects: true,
    sessionCookie: "",
  },
  github: {
    // baseUrl: 'https://github.mycompany.com:123/etc',
    // apiUrl: 'https://api.github.mycompany.com',
    owner: '{{repository owner (user or organization)}}', // 필수
    ownerIsOrg: false,
    token: '{{token}}', // 필수
    token_owner: '{{token_owner}}', // 필수
    repo: '{{repo}}',
    recreateRepo: false,
  },
  s3: {
    accessKeyId: '{{accessKeyId}}',
    secretAccessKey: '{{secretAccessKey}}',
    bucket: 'my-gitlab-bucket',
  },
  usermap: {
    'username.gitlab.1': 'username.github.1', // 선택
    'username.gitlab.2': 'username.github.2',
  },
  projectmap: {
    'gitlabgroup/projectname.1': 'GitHubOrg/projectname.1', // 선택
    'gitlabgroup/projectname.2': 'GitHubOrg/projectname.2',
  },
  conversion: {
    useLowerCaseLabels: true,
  },
  transfer: {
    description: true,
    milestones: true,
    labels: true,
    issues: true,
    mergeRequests: true,
    releases: true,
  },
  dryRun: false,
  useIssueImportAPI: true,
  usePlaceholderMilestonesForMissingMilestones: true,
  usePlaceholderIssuesForMissingIssues: true,
  useReplacementIssuesForCreationFails: true,
  useIssuesForAllMergeRequests: false,
  filterByLabel: undefined,
  trimOversizedLabelDescriptions: false,
  skipMergeRequestStates: [],
  skipMatchingComments: [],
  mergeRequests: {
    logFile: './merge-requests.json',
    log: false,
  },
} as Settings;

 

2-1. gitlab 옵션

 

- token: Gitlab 저장소 접근 권한이 있는 본인의 AccessToken을 입력하면 된다. AccessToken 발급 방법은 공식 문서에 자세히 적혀있다. 

 

- projectId: 마이그레이션 하고자 하는 저장소의 아이디를 입력하면 된다. 저장소의 아이디를 확인하는 방법은 여러가지가 있지만, 필자는 따로 API 콜을 하기 귀찮은 관계로 웹에서 저장소에 들어갔을 때 나오는 API 응답 값으로 아이디를 확인하였다.

POST /api/graphql 

 

위 API 의 응답값은 대략 아래와 같은데, 그 중 project > id 의 숫자 값이 projectId 이다.

 

 {
        "data": {
            "project": {
                "id": "gid://gitlab/Project/178", // 178이 projectId이다.
               ...
              }
           ...
           }
...
}

 

2-2. github 옵션

 

- owner: Repository가 속해있는 계정 이름을 작성하면 된다. 쉽게 생각하면, Migration 결과물이 위치할 Repository를 접속했을 때의 웹 주소에서 확인이 가능하다.

https://github.com/Seung-o/migrated 
> 여기서 owner는 "Seung-o"이다.

 

- token: Github의 개인 엑세스 토큰을 입력하면 된다. 이 역시 공식 문서에서 쉽게 확인 가능하다.

 

- token-owner: 토큰 발급을 받은 계정의 이름을 적으면 된다.

 

2-3. 기타 옵션

 

필자는 usermap 옵션도 사용하였다. 단순하게 key는 Gitlab에서의 사용자 이름, value는 Github에서의 사용자 이름을 입력하면 된다. 그러면, 리뷰 등에서 있던 언급 혹은 PR의 assignee 등도 모두 정상적으로 이동된다.

 

 

3. 라이브러리를 실행한다.

npm run start

 

4. 터미널에 나오는 로그를 보며, 마이그레이션이 정상적으로 진행되는지 확인한다.

 

여기까지, Gitlab 에서 Github로의 이전기를 마친다. 사실 이것뿐만 아니라, PR Template이나 CI/CD 등 옮겨야할 것이 아직도 많다. 이것들은 기회가 될 때, 글로 남겨보도록 하겠다.