SSAFY에서는 Gitlab을 이용하게 된다. 1학기의 대부분의 과제 뿐 아니라 2학기 프로젝트도 Gitlab에서 진행된다. 사실 Git Repository를 미러링하는 것은 간단하게 가능하다.
나는 공통 프로젝트 때 함께 한 팀원들의 도움을 받아 깃랩의 MR(Merge Request)를 적극 활용하여 코드리뷰를 남기고 문서화하였다. 하지만 Gitlab의 MR은 Github의 PR과는 달라서 mirror로는 이전이 되지 않는다. 방법을 찾다가 node-gitlab-2-github라는 깃허브 레포지토리를 발견하고, 이를 이용하여 MR 내용들을 mirgration한 과정을 정리하려 한다. 이를 사용하여 gitlab에서 github migration을 한 사람은 구글링하면 쉽게 찾아볼 수 있어 많은 도움을 받았다. 하지만 해당 레포지토리에서 제공하는 S3를 이용하여 이미지를 이관하는 것을 사용한 사례는 나오지 않아 추가하여 정리해보고자 한다.
Git Repository Mirroring
Git Repository를 미러링하는 것은 간단하게 가능하다. 이 외에도 Gitlab 자체에서 미러링 기능을 지원하므로 이를 사용하면 더 간단하게 미러링이 가능하다고 하는데, 이를 찾지 못해 그냥 터미널에서 수행하였다.
1. git clone --mirror를 하여 기존 Gitlab repository를 복사한다.
git clone --mirror https://(gitlab https url)
2. Github에서 미러를 수행할 레포지토리를 생성한다.
3. Github에 Gitlab 이메일 추가
mirror push 이전에 팀원들에게 각각의 Github에서 Gitlab에서 사용중인 email을 추가해달라고 요청한다. 이렇게 해야 mirror push를 수행했을 때 각각의 커밋들에 대해 적절히 매핑된다. mirror push 이후에 email을 추가했을 때 적용되는지는 아직 확인하지 못했다.
4. 다음과 같이 mirror push를 하면 migration이 된다.
git push --mirror https://github.com/{github_username}/{github_reponame}.git
node-gitlab-2-github 사용하기
https://github.com/piceaTech/node-gitlab-2-github/tree/master
GitHub - piceaTech/node-gitlab-2-github: Migrate Issues, milestones etc from gitlab to github
Migrate Issues, milestones etc from gitlab to github - piceaTech/node-gitlab-2-github
github.com
위의 레포지토리를 사용하여 Gitlab의 프로젝트에 속한 MR들을 Github로 이관하고자 한다. 처음에 MR이 PR과 같은 것이라고 생각해서 쉽게 될 줄 알았는데, 사실 둘을 다른 것이라고 한다. 그래서 위의 레포지토리를 이용하여 이관하려 했는데, MR이 해당하는 브랜치가 없다면 PR을 생성할 수 없어 위의 레포지토리는 이를 이슈로 생성하고, gitlab merge request라는 라벨을 달아 이를 구분하는 방식으로 되어 있다.
일단 레포지토리의 README에서는 다음과 같이 사용방법을 설명하고 있다.
1. cp sample_settings.ts settings.ts
2. edit settings.ts
3. run npm run start
이를 좀 더 자세히, 단계별로 기록하고자 한다. 특히 setting 작성 부분을 기록할 것이다.
0. node, npm 설치 및 npm i
레포지토리 이름에서도 알 수 있듯이, 해당 레포지토리는 node 기반이므로, node와 npm이 설치된 환경이여야 한다. 만약 설치가 되어있지 않다면, 레포지토리 아랫쪽에 나온 것처럼 Docker를 사용하는 것도 좋을 것 같다.
1. 토큰 발급하기
node-gitlab-2-github가 gitlab과 github에 접근하기 위해서는 각각에 대한 토큰이 필요하다. gitlab에 대해서는 해당 레포지토리와 이슈를 읽을 수 있는 권한이 부여된 토큰이, github에 대해서는 특정 레포지토리에 작성할 수 있는 권한이 부여된 토큰이 필요하다.
먼저 깃랩의 경우, 다음과 같이 api, read_repository 권한을 부여하여 토큰을 생성한다.
깃허브의 경우, Setting으로 진입하면 사이드바 최하단에 Developer Settings에서 Personal access tokens에서 토큰을 생성할 수 있다. node-gitlab-2-github는 githubdptj 커밋을 생성하고, issue를 생성할 수 있어야 하므로, 다음과 같이 권한이 있는 토큰을 발급하면 된다.
2. S3 생성하기
gitlab은 api상으로 첨부파일에 대한 다운로드를 제공하지 않는다. 그래서 node-gitlab-2-github는 해당 첨부파일들을 이진 파일로 다운받고 이를 S3에 업로드한 후, 해당 주소를 기존 본문에서 replace하여 github에 업로드하는 방식으로 이관한다.
S3에서 버킷을 생성한다.
해당 버킷에 접근할 수 있는 IAM 사용자를 생성하고, 권한 정책에 'AmazonS3FullAccess'를 부여한다.
S3의 버킷에서 버킷 정책을 json 파일 형태로 지정할 수 있다. 위에서 생성한 IAM 사용자가 이 버킷에 이미지 업로드가 가능하도록 한다. 또한 Object를 읽어오는 것은 public access가 가능하도록 지정한다.
먼저 S3 버킷 콘솔에서 생성한 S3로 들어가 아래와 같이 권한 탭을 클릭한다.
하단으로 스크롤을 내려 '버킷 정책'을 찾아 편집을 클릭한다.
편집에서 제공하는 정책 생성기를 이용하거나, 아래와 같이 작성하면 된다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "{생성한 IAM 사용자의 accessKey}"
},
"Action": "s3:*",
"Resource": [
"{S3 버킷의 Amazon 리소스 이름(ARN)}",
"{S3 버킷의 Amazon 리소스 이름(ARN)}/*"
]
},
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"{S3 버킷의 Amazon 리소스 이름(ARN)}",
"{S3 버킷의 Amazon 리소스 이름(ARN)}/*"
]
}
]
}
3. cp sample_settings.ts settings.ts
레포지토리에서 이관 설정을 할 수 있는 settings.ts 파일의 샘플을 제공하고 있다. sample_settings.ts는 다음과 같은 형태이다. 이를 복사하여 같은 형태로 이관 설정을 할 것이다.
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',
region: null,
},
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;
나는 이 중에서 다음 부분을 채워 넣었다. 각각의 필드에 대한 자세한 내용은 github README에 쓰여 있다.
- gitlab
- url: gitlab 프로젝트가 소속된 gitlab url. 나는 SSAFY의 gitlab에서 작업한 레포지토리를 이관하고자 하므로 해당 url을 기입하였다.
- token: 이전 단계에서 Gitlab의 Settings/AccesToken에서 발급받은 gitlab의 api와 read_repository 권한이 부여된 access token
- projectId: 이관할 프로젝트의 프로젝트 ID. 하단의 그림과 같이 Gitlab의 프로젝트 페이지에서 우측에 점 세개 버튼을 누르면 확인할 수 있다.
- sessionCookie: Gitlab의 API는 첨부 파일 다운로드를 허용하지 않고, HTTP를 통해 이미지만 다운로드 할 수 있어, 이를 해결하기 위해 Gitlab 로그인 후 브라우저에서 개발자 도구 > Application > Cookies에서 gitlab url에 해당하는 "gitlab_session"이라는 이름의 세션 쿠키의 값을 가져와서 기입하여 우회하여 이진 파일을 마이그레이션 할 수 있다.
- github
- owner: 이관할 github의 레포지토리를 소유할 organization이나 user명
- token: 이전 단계에서 Settings/Developer settings/Personal Access Tokens 에서 생성한 repo 권한이 부여된 토큰.
- token_owner: 위의 토큰을 발급한 github user의 유저명
- repo: 이관할 레포지토리의 이름
- S3: 이슈에 속한 첨부 파일을 이관하기 위해서 S3를 사용한다.
- accesKeyId, secretAccessKey: 사용할 S3 버켓에 대한 쓰기 권한이 있는 유저의 accessKey와 secretKey
- bucket: 사용할 S3의 버킷명. public access가 가능해야 해당 파일을 깃허브 이슈에서 접근하여 보여줄 수 있다.
- region: S3 버킷의 지역.
- usermap: 깃랩의 유저명과 깃허브의 유저명을 여기서 매핑한다. 이는 이슈 생성 시, assignee를 매핑하는 데 사용된다.
- gitlab의 유저명은 각 사용자에게 부여된 앞에 @가 있는 부분이다. (@는 생략)
- Github의 유저명은 각 사용자의 profile에 있는 (닉네임이 아닌) 사용자명이다.
4. npm run start를 실행하고 로그를 관찰한다.