Skip to content

Commit a9f2cd6

Browse files
authored
Merge pull request #130 from mdbenito/feature/recreate-repo
Option to recreate GitHub repository
2 parents 5abd4e7 + 8c9a977 commit a9f2cd6

8 files changed

Lines changed: 129 additions & 59 deletions

File tree

.vscode/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"src/index.ts"
2020
],
2121
"protocol": "inspector",
22-
"sourceMaps": true
22+
"sourceMaps": true,
23+
"console": "integratedTerminal"
2324
}
2425
]
2526
}

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ Set to the user name of the user whose token is used (see above). This is requir
8282

8383
What is the name of the new repo
8484

85+
#### github.recreateRepo
86+
87+
If true (default is false), we will try to delete the destination github repository if present, and (re)create it. The github token must be granted `delete_repo` scope. The newly created repository will be made private by default.
88+
89+
This is useful when debugging this tool or a specific migration. You will always be prompted for confirmation.
90+
8591
### s3 (optional)
8692

8793
S3 can be used to store attachments from issues. If omitted, `has attachment` label will be added to GitHub issue.

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@
3333
"aws-sdk": "^2.1053.0",
3434
"axios": "^0.24.0",
3535
"mime-types": "^2.1.34",
36+
"readline-sync": "^1.4.10",
3637
"ts-node": "^10.4.0"
3738
},
3839
"devDependencies": {
3940
"@types/mime-types": "^2.1.1",
40-
"@types/node": "^14.0.20",
41+
"@types/node": "^14.18.5",
42+
"@types/readline-sync": "^1.4.4",
4143
"husky": "^7.0.4",
4244
"lint-staged": "^12.1.7",
4345
"prettier": "^2.5.1",

sample_settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default {
1313
token: '{{token}}',
1414
token_owner: '{{token_owner}}',
1515
repo: '{{repo}}',
16+
recreateRepo: false,
1617
},
1718
s3: {
1819
accessKeyId: '{{accessKeyId}}',

src/githubHelper.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,4 +1260,34 @@ export class GithubHelper {
12601260
const ref = path && line ? `${path} line ${line}` : `${head_sha}`;
12611261
return `Commented on [${ref}](${repoLink}/compare/${base_sha}..${head_sha}${slug})\n\n`;
12621262
}
1263+
1264+
/**
1265+
* Deletes the GH repository, then creates it again.
1266+
*/
1267+
async recreateRepo() {
1268+
let params = {
1269+
owner: this.githubOwner,
1270+
repo: this.githubRepo,
1271+
};
1272+
1273+
try {
1274+
console.log(`Deleting repo ${params.owner}/${params.repo}...`);
1275+
await this.githubApi.repos.delete(params);
1276+
console.log('\t...done.');
1277+
} catch (err) {
1278+
if (err.status == 404) console.log(' not found.');
1279+
else console.error(`\n\tSomething went wrong: ${err}.`);
1280+
}
1281+
try {
1282+
console.log(`Creating repo ${params.owner}/${params.repo}...`);
1283+
await this.githubApi.repos.createForAuthenticatedUser({
1284+
name: this.githubRepo,
1285+
private: true,
1286+
});
1287+
console.log('\t...done.');
1288+
} catch (err) {
1289+
console.error(`\n\tSomething went wrong: ${err}.`);
1290+
}
1291+
await utils.sleep(this.delayInMs);
1292+
}
12631293
}

src/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Octokit as GitHubApi } from '@octokit/rest';
66
import { throttling } from '@octokit/plugin-throttling';
77
import { Gitlab } from '@gitbeaker/node';
88

9+
import { default as readlineSync } from 'readline-sync';
910
import * as fs from 'fs';
1011

1112
import AWS from 'aws-sdk';
@@ -101,11 +102,28 @@ if (!settings.gitlab.projectId) {
101102
gitlabHelper.listProjects();
102103
} else {
103104
// user has chosen a project
105+
if (settings.github.recreateRepo === true) {
106+
recreate();
107+
}
104108
migrate();
105109
}
106110

107111
// ----------------------------------------------------------------------------
108112

113+
/**
114+
* Asks for confirmation and maybe recreates the GitHub repository.
115+
*/
116+
async function recreate() {
117+
readlineSync.setDefaultOptions({
118+
limit: ['no', 'yes'],
119+
limitMessage: 'Please enter yes or no',
120+
defaultInput: 'no',
121+
});
122+
const ans = readlineSync.question('Delete and recreate? [yes/no] ');
123+
if (ans == 'yes') await githubHelper.recreateRepo();
124+
else console.log("OK, I won't delete anything then.");
125+
}
126+
109127
/*
110128
* TODO description
111129
*/

src/settings.ts

Lines changed: 58 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,58 @@
1-
export default interface Settings {
2-
debug: boolean;
3-
gitlab: GitlabSettings;
4-
github: GithubSettings;
5-
usermap: {
6-
[key: string]: string;
7-
};
8-
projectmap: {
9-
[key: string]: string;
10-
};
11-
conversion: {
12-
useLowerCaseLabels: boolean;
13-
};
14-
transfer: {
15-
description: boolean;
16-
milestones: boolean;
17-
labels: boolean;
18-
issues: boolean;
19-
mergeRequests: boolean;
20-
releases: boolean;
21-
};
22-
useIssueImportAPI: boolean;
23-
usePlaceholderIssuesForMissingIssues: boolean;
24-
useReplacementIssuesForCreationFails: boolean;
25-
useIssuesForAllMergeRequests: boolean;
26-
filterByLabel: string | null;
27-
skipMergeRequestStates: string[];
28-
skipMatchingComments: string[];
29-
mergeRequests: {
30-
logFile: string;
31-
log: boolean;
32-
};
33-
s3?: S3Settings;
34-
}
35-
36-
export interface GithubSettings {
37-
baseUrl?: string;
38-
owner: string;
39-
token: string;
40-
token_owner: string;
41-
repo: string;
42-
timeout?: number;
43-
username?: string; // when is this set???
44-
}
45-
46-
export interface GitlabSettings {
47-
url?: string;
48-
token: string;
49-
projectId: number;
50-
sessionCookie: string;
51-
}
52-
53-
export interface S3Settings {
54-
accessKeyId: string;
55-
secretAccessKey: string;
56-
bucket: string;
57-
}
1+
export default interface Settings {
2+
debug: boolean;
3+
gitlab: GitlabSettings;
4+
github: GithubSettings;
5+
usermap: {
6+
[key: string]: string;
7+
};
8+
projectmap: {
9+
[key: string]: string;
10+
};
11+
conversion: {
12+
useLowerCaseLabels: boolean;
13+
};
14+
transfer: {
15+
description: boolean;
16+
milestones: boolean;
17+
labels: boolean;
18+
issues: boolean;
19+
mergeRequests: boolean;
20+
releases: boolean;
21+
};
22+
useIssueImportAPI: boolean;
23+
usePlaceholderIssuesForMissingIssues: boolean;
24+
useReplacementIssuesForCreationFails: boolean;
25+
useIssuesForAllMergeRequests: boolean;
26+
filterByLabel: string | null;
27+
skipMergeRequestStates: string[];
28+
skipMatchingComments: string[];
29+
mergeRequests: {
30+
logFile: string;
31+
log: boolean;
32+
};
33+
s3?: S3Settings;
34+
}
35+
36+
export interface GithubSettings {
37+
baseUrl?: string;
38+
owner: string;
39+
token: string;
40+
token_owner: string;
41+
repo: string;
42+
timeout?: number;
43+
username?: string; // when is this set???
44+
recreateRepo?: boolean;
45+
}
46+
47+
export interface GitlabSettings {
48+
url?: string;
49+
token: string;
50+
projectId: number;
51+
sessionCookie: string;
52+
}
53+
54+
export interface S3Settings {
55+
accessKeyId: string;
56+
secretAccessKey: string;
57+
bucket: string;
58+
}

0 commit comments

Comments
 (0)