generated from austenstone/typescript-node
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update package.json with new name, description, and dependencies
- Loading branch information
1 parent
c625502
commit b1321d7
Showing
8 changed files
with
1,048 additions
and
175 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
type Link = { | ||
href: string; | ||
name: string; | ||
}; | ||
|
||
type Rendered = { | ||
raw: string; | ||
markup: string; | ||
html: string; | ||
}; | ||
|
||
type Author = { | ||
type: string; | ||
}; | ||
|
||
type Reviewer = { | ||
type: string; | ||
}; | ||
|
||
type Participant = { | ||
type: string; | ||
}; | ||
|
||
type PullRequest = { | ||
type: string; | ||
links: { | ||
self: Link; | ||
html: Link; | ||
commits: Link; | ||
approve: Link; | ||
diff: Link; | ||
diffstat: Link; | ||
comments: Link; | ||
activity: Link; | ||
merge: Link; | ||
decline: Link; | ||
}; | ||
id: number; | ||
title: string; | ||
rendered: { | ||
title: Rendered; | ||
description: Rendered; | ||
reason: Rendered; | ||
}; | ||
summary: { | ||
raw: string; | ||
markup: string; | ||
html: string; | ||
}; | ||
state: string; | ||
author: Author; | ||
source: { | ||
branch: { | ||
name: string; | ||
}; | ||
repository: Repository; | ||
}; | ||
destination: { | ||
branch: { | ||
name: string; | ||
}; | ||
repository: Repository; | ||
}; | ||
merge_commit: { | ||
hash: string; | ||
}; | ||
comment_count: number; | ||
task_count: number; | ||
close_source_branch: boolean; | ||
closed_by: { | ||
type: string; | ||
}; | ||
reason: string; | ||
created_on: string; | ||
updated_on: string; | ||
reviewers: Reviewer[]; | ||
participants: Participant[]; | ||
}; | ||
|
||
type PullRequestResponse = { | ||
size: number; | ||
page: number; | ||
pagelen: number; | ||
next: string; | ||
previous: string; | ||
values: PullRequest[]; | ||
}; | ||
|
||
type Clone = { | ||
href: string; | ||
name: string; | ||
}; | ||
|
||
type Owner = { | ||
type: string; | ||
}; | ||
|
||
type Project = { | ||
type: string; | ||
}; | ||
|
||
type MainBranch = { | ||
type: string; | ||
}; | ||
|
||
type Repository = { | ||
type: string; | ||
links: { | ||
self: Link; | ||
html: Link; | ||
avatar: Link; | ||
pullrequests: Link; | ||
commits: Link; | ||
forks: Link; | ||
watchers: Link; | ||
downloads: Link; | ||
clone: Clone[]; | ||
hooks: Link; | ||
}; | ||
uuid: string; | ||
full_name: string; | ||
is_private: boolean; | ||
scm: string; | ||
owner: Owner; | ||
name: string; | ||
description: string; | ||
created_on: string; | ||
updated_on: string; | ||
size: number; | ||
language: string; | ||
has_issues: boolean; | ||
has_wiki: boolean; | ||
fork_policy: string; | ||
project: Project; | ||
mainbranch: MainBranch; | ||
}; | ||
|
||
type RepositoryResponse = { | ||
size: number; | ||
page: number; | ||
pagelen: number; | ||
next: string; | ||
previous: string; | ||
values: Repository[]; | ||
}; | ||
|
||
export { PullRequest, PullRequestResponse, Repository, RepositoryResponse } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Migrate } from "./migrate"; | ||
import inquirer from 'inquirer'; | ||
|
||
const questions = [] as { | ||
type: string; | ||
name: string; | ||
message: string; | ||
}[]; | ||
|
||
if (!process.env.GITHUB_TOKEN) { | ||
questions.push({ | ||
type: 'input', | ||
name: 'githubToken', | ||
message: 'What is your GitHub token?' | ||
}); | ||
} | ||
if (!process.env.GITHUB_ORG) { | ||
questions.push({ | ||
type: 'input', | ||
name: 'githubOwner', | ||
message: 'What is the destination GitHub org?' | ||
}); | ||
} | ||
|
||
if (!process.env.BITBUCKET_TOKEN) { | ||
questions.push({ | ||
type: 'input', | ||
name: 'bitbucketToken', | ||
message: 'What is your Bitbucket token?' | ||
}); | ||
} | ||
if (!process.env.BITBUCKET_WORKSPACE) { | ||
questions.push({ | ||
type: 'input', | ||
name: 'bitbucketWorkspace', | ||
message: 'What is the source Bitbucket workspace?' | ||
}); | ||
} | ||
|
||
inquirer.prompt(questions).then(answers => { | ||
const migrate = new Migrate({ | ||
bitbucketToken: process.env.BITBUCKET_TOKEN || answers.bitbucketToken, | ||
bitbucketWorkspace: process.env.BITBUCKET_WORKSPACE || answers.bitbucketWorkspace, | ||
githubToken: process.env.GITHUB_TOKEN || answers.githubToken, | ||
githubOwner: process.env.GITHUB_ORG || answers.githubOwner | ||
}); | ||
migrate.run(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { PullRequest, PullRequestResponse, Repository, RepositoryResponse } from './bitbucket.d'; | ||
|
||
export class BitBucket { | ||
init = { | ||
headers: { | ||
'Authorization': 'Bearer <access_token>', | ||
'Accept': 'application/json' | ||
} | ||
}; | ||
repos: Repository[] = []; | ||
prs: { | ||
[repo: string]: PullRequest[] | ||
} = {}; | ||
|
||
constructor(token: string) { | ||
this.init.headers.Authorization = `Bearer ${token}` | ||
} | ||
|
||
async listAllPullRequests(workspace: string) { | ||
if (this.repos.length === 0) { | ||
this.repos = await this.listRepositories(workspace); | ||
} | ||
for (const repo of this.repos) { | ||
this.prs[repo.name] = await this.listPullRequests(workspace, repo.name); | ||
} | ||
return this.prs; | ||
} | ||
|
||
async listPullRequests(workspace: string, repo_slug: string) { | ||
if (this.prs && this.prs[repo_slug]) return this.prs[repo_slug]; | ||
let response: PullRequestResponse; | ||
let prs: PullRequest[] = []; | ||
do { | ||
response = await fetch(`https://api.bitbucket.org/2.0/repositories/${workspace}/${repo_slug}/pullrequests`, this.init) | ||
.then(res => res.json() as Promise<PullRequestResponse>); | ||
prs.push(...response.values); | ||
} while (response.next) | ||
return prs; | ||
} | ||
|
||
async listRepositories(workspace: string) { | ||
if (this.repos) return this.repos; | ||
let response: RepositoryResponse; | ||
let repos: Repository[] = []; | ||
do { | ||
response = await fetch(`https://api.bitbucket.org/2.0/repositories/${workspace}`, this.init) | ||
.then(res => res.json() as Promise<RepositoryResponse>); | ||
repos.push(...response.values); | ||
} while (response.next) | ||
this.repos = repos; | ||
return repos; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Octokit } from '@octokit/rest'; | ||
import { Endpoints } from '@octokit/types'; | ||
|
||
export class GitHub { | ||
octokit: Octokit; | ||
|
||
constructor(token: string) { | ||
this.octokit = new Octokit({ | ||
auth: token, | ||
}); | ||
} | ||
|
||
async createPullRequest(request: Endpoints["POST /repos/{owner}/{repo}/pulls"]["parameters"]) { | ||
return this.octokit.pulls.create(request); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { BitBucket } from "./bitbucket"; | ||
import { GitHub } from "./github"; | ||
|
||
export interface MigrateOptions { | ||
bitbucketWorkspace?: string; | ||
githubOwner?: string; | ||
bitbucketToken: string; | ||
githubToken: string; | ||
} | ||
|
||
export class Migrate { | ||
bitbucket: BitBucket; | ||
github: GitHub; | ||
options: MigrateOptions; | ||
|
||
constructor(options: MigrateOptions) { | ||
this.options = options; | ||
this.bitbucket = new BitBucket(this.options.bitbucketToken); | ||
this.github = new GitHub(this.options.githubToken); | ||
} | ||
|
||
async run() { | ||
if (!this.options.bitbucketWorkspace) throw new Error('bitbucketWorkspace input is required'); | ||
if (!this.options.githubOwner) throw new Error('githubOwner input is required'); | ||
const pullRequests = await this.bitbucket.listAllPullRequests(this.options.bitbucketWorkspace); | ||
for (const [repo, prs] of Object.entries(pullRequests)) { | ||
for (const pr of prs) { | ||
console.log(`Creating PR for ${repo} - ${pr.title}`); | ||
try { | ||
await this.github.createPullRequest({ | ||
owner: this.options.githubOwner, | ||
repo, | ||
title: pr.title, | ||
head: pr.source.branch.name, | ||
base: pr.destination.branch.name, | ||
body: pr.summary.markup, | ||
head_repo: pr.source?.repository?.full_name, | ||
draft: pr.state === 'OPEN' | ||
}); | ||
} catch (err) { | ||
if ((err as any).status === 422) { | ||
console.log(`PR for ${repo} - ${pr.title} already exists`); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
} | ||
} | ||
console.log(`Finished migrating ${Object.keys(pullRequests).length} repositories and ${Object.values(pullRequests).flat().length} pull requests`); | ||
} | ||
} |