From 474c2c8e608336ac053f30002714f12ae37a1caa Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 10:35:31 +0100 Subject: [PATCH 1/8] Add option (and confirmation prompt) to recreate github repository --- .vscode/launch.json | 3 +- package-lock.json | 17 +++++-- package.json | 4 +- sample_settings.ts | 1 + src/githubHelper.ts | 25 ++++++++++ src/index.ts | 15 ++++++ src/settings.ts | 115 ++++++++++++++++++++++---------------------- 7 files changed, 118 insertions(+), 62 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a103ef6..6442c72 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,7 +19,8 @@ "src/index.ts" ], "protocol": "inspector", - "sourceMaps": true + "sourceMaps": true, + "console": "integratedTerminal" } ] } diff --git a/package-lock.json b/package-lock.json index 36de451..146c9d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -336,6 +336,12 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.5.tgz", "integrity": "sha512-LMy+vDDcQR48EZdEx5wRX1q/sEl6NdGuHXPnfeL8ixkwCOSZ2qnIyIZmcCbdX0MeRqHhAcHmX+haCbrS8Run+A==" }, + "@types/readline-sync": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@types/readline-sync/-/readline-sync-1.4.4.tgz", + "integrity": "sha512-cFjVIoiamX7U6zkO2VPvXyTxbFDdiRo902IarJuPVxBhpDnXhwSaVE86ip+SCuyWBbEioKCkT4C88RNTxBM1Dw==", + "dev": true + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -690,9 +696,9 @@ "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=" }, "follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==" + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" }, "form-data": { "version": "4.0.0", @@ -1249,6 +1255,11 @@ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" }, + "readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==" + }, "resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", diff --git a/package.json b/package.json index c4e5f9a..c4e5125 100644 --- a/package.json +++ b/package.json @@ -33,11 +33,13 @@ "aws-sdk": "^2.1053.0", "axios": "^0.24.0", "mime-types": "^2.1.34", + "readline-sync": "^1.4.10", "ts-node": "^10.4.0" }, "devDependencies": { "@types/mime-types": "^2.1.1", - "@types/node": "^14.0.20", + "@types/node": "^14.18.5", + "@types/readline-sync": "^1.4.4", "husky": "^7.0.4", "lint-staged": "^12.1.7", "prettier": "^2.5.1", diff --git a/sample_settings.ts b/sample_settings.ts index 61869fb..710c78f 100644 --- a/sample_settings.ts +++ b/sample_settings.ts @@ -13,6 +13,7 @@ export default { token: '{{token}}', token_owner: '{{token_owner}}', repo: '{{repo}}', + recreateRepo: false, }, s3: { accessKeyId: '{{accessKeyId}}', diff --git a/src/githubHelper.ts b/src/githubHelper.ts index 39a4e7f..c8725df 100644 --- a/src/githubHelper.ts +++ b/src/githubHelper.ts @@ -1260,4 +1260,29 @@ export class GithubHelper { const ref = path && line ? `${path} line ${line}` : `${head_sha}`; return `Commented on [${ref}](${repoLink}/compare/${base_sha}..${head_sha}${slug})\n\n`; } + + async recreateRepo() { + let params = { + owner: this.githubOwner, + repo: this.githubRepo, + }; + + try { + process.stdout.write(`Deleting repo ${params.owner}/${params.repo}...`); + await this.githubApi.repos.delete(params); + process.stdout.write(' done.'); + } catch (err) { + if (err.status == 404) process.stdout.write(' not found.'); + else console.error(`\n\tSomething went wrong: ${err}.`); + } + try { + process.stdout.write(`Creating repo ${params.owner}/${params.repo}...`); + await this.githubApi.repos.createForAuthenticatedUser({ + name: this.githubRepo, + }); + process.stdout.write(' done.'); + } catch (err) { + console.error(`\n\tSomething went wrong: ${err}.`); + } + } } diff --git a/src/index.ts b/src/index.ts index e6332b9..7237725 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import { Octokit as GitHubApi } from '@octokit/rest'; import { throttling } from '@octokit/plugin-throttling'; import { Gitlab } from '@gitbeaker/node'; +import { default as readlineSync } from 'readline-sync'; import * as fs from 'fs'; import AWS from 'aws-sdk'; @@ -101,11 +102,25 @@ if (!settings.gitlab.projectId) { gitlabHelper.listProjects(); } else { // user has chosen a project + if (settings.github.recreateRepo === true) { + recreate(); + } migrate(); } // ---------------------------------------------------------------------------- +async function recreate() { + readlineSync.setDefaultOptions({ + limit: ['no', 'yes'], + limitMessage: 'Please enter yes or no', + defaultInput: 'no', + }); + const ans = readlineSync.question('Delete and recreate? [yes/no] '); + if (ans == 'yes') await githubHelper.recreateRepo(); + else console.log("OK, I won't delete anything then."); +} + /* * TODO description */ diff --git a/src/settings.ts b/src/settings.ts index 0951fab..9845356 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,57 +1,58 @@ -export default interface Settings { - debug: boolean; - gitlab: GitlabSettings; - github: GithubSettings; - usermap: { - [key: string]: string; - }; - projectmap: { - [key: string]: string; - }; - conversion: { - useLowerCaseLabels: boolean; - }; - transfer: { - description: boolean; - milestones: boolean; - labels: boolean; - issues: boolean; - mergeRequests: boolean; - releases: boolean; - }; - useIssueImportAPI: boolean; - usePlaceholderIssuesForMissingIssues: boolean; - useReplacementIssuesForCreationFails: boolean; - useIssuesForAllMergeRequests: boolean; - filterByLabel: string | null; - skipMergeRequestStates: string[]; - skipMatchingComments: string[]; - mergeRequests: { - logFile: string; - log: boolean; - }; - s3?: S3Settings; -} - -export interface GithubSettings { - baseUrl?: string; - owner: string; - token: string; - token_owner: string; - repo: string; - timeout?: number; - username?: string; // when is this set??? -} - -export interface GitlabSettings { - url?: string; - token: string; - projectId: number; - sessionCookie: string; -} - -export interface S3Settings { - accessKeyId: string; - secretAccessKey: string; - bucket: string; -} +export default interface Settings { + debug: boolean; + gitlab: GitlabSettings; + github: GithubSettings; + usermap: { + [key: string]: string; + }; + projectmap: { + [key: string]: string; + }; + conversion: { + useLowerCaseLabels: boolean; + }; + transfer: { + description: boolean; + milestones: boolean; + labels: boolean; + issues: boolean; + mergeRequests: boolean; + releases: boolean; + }; + useIssueImportAPI: boolean; + usePlaceholderIssuesForMissingIssues: boolean; + useReplacementIssuesForCreationFails: boolean; + useIssuesForAllMergeRequests: boolean; + filterByLabel: string | null; + skipMergeRequestStates: string[]; + skipMatchingComments: string[]; + mergeRequests: { + logFile: string; + log: boolean; + }; + s3?: S3Settings; +} + +export interface GithubSettings { + baseUrl?: string; + owner: string; + token: string; + token_owner: string; + repo: string; + timeout?: number; + username?: string; // when is this set??? + recreateRepo?: boolean; +} + +export interface GitlabSettings { + url?: string; + token: string; + projectId: number; + sessionCookie: string; +} + +export interface S3Settings { + accessKeyId: string; + secretAccessKey: string; + bucket: string; +} From 99ae8548e9e1df8308ed248db75874ab3e676911 Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 10:39:56 +0100 Subject: [PATCH 2/8] Document --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 875f510..d63dd40 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,10 @@ Set to the user name of the user whose token is used (see above). This is requir What is the name of the new repo +#### github.recreateRepo + +If true (default is false), we will try to delete the destination github repository if present, and (re)create it. This is useful when debugging this tool or a specific migration. You will always be prompted for confirmation. + ### s3 (optional) S3 can be used to store attachments from issues. If omitted, `has attachment` label will be added to GitHub issue. From dd952b2ee02e18b2d37e37863ee1a990735043ad Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 10:42:54 +0100 Subject: [PATCH 3/8] Update doc about token --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d63dd40..b204dfd 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,9 @@ What is the name of the new repo #### github.recreateRepo -If true (default is false), we will try to delete the destination github repository if present, and (re)create it. This is useful when debugging this tool or a specific migration. You will always be prompted for confirmation. +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. + +This is useful when debugging this tool or a specific migration. You will always be prompted for confirmation. ### s3 (optional) From 4ad934e636aa15be5b5efdb59ca1835ceb65df26 Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 10:47:13 +0100 Subject: [PATCH 4/8] Missing docstring --- src/githubHelper.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/githubHelper.ts b/src/githubHelper.ts index c8725df..08b6085 100644 --- a/src/githubHelper.ts +++ b/src/githubHelper.ts @@ -1261,6 +1261,9 @@ export class GithubHelper { return `Commented on [${ref}](${repoLink}/compare/${base_sha}..${head_sha}${slug})\n\n`; } + /** + * Asks for confirmation and then maybe deletes the GH repository, then creates it again. + */ async recreateRepo() { let params = { owner: this.githubOwner, From 388a1080dca8df538f2604ed50bfc2ec4318c8f4 Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 10:49:19 +0100 Subject: [PATCH 5/8] Fix docstrings --- src/githubHelper.ts | 2 +- src/index.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/githubHelper.ts b/src/githubHelper.ts index 08b6085..83b469a 100644 --- a/src/githubHelper.ts +++ b/src/githubHelper.ts @@ -1262,7 +1262,7 @@ export class GithubHelper { } /** - * Asks for confirmation and then maybe deletes the GH repository, then creates it again. + * Deletes the GH repository, then creates it again. */ async recreateRepo() { let params = { diff --git a/src/index.ts b/src/index.ts index 7237725..3ecbc53 100644 --- a/src/index.ts +++ b/src/index.ts @@ -110,6 +110,9 @@ if (!settings.gitlab.projectId) { // ---------------------------------------------------------------------------- +/** + * Asks for confirmation and maybe recreates the GitHub repository. + */ async function recreate() { readlineSync.setDefaultOptions({ limit: ['no', 'yes'], From e50c12c635a4ed83ce7bd21537b2d6d473898f90 Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 10:57:26 +0100 Subject: [PATCH 6/8] Use console.log instead of stdout.write --- src/githubHelper.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/githubHelper.ts b/src/githubHelper.ts index 83b469a..c537e8a 100644 --- a/src/githubHelper.ts +++ b/src/githubHelper.ts @@ -1271,19 +1271,19 @@ export class GithubHelper { }; try { - process.stdout.write(`Deleting repo ${params.owner}/${params.repo}...`); + console.log(`Deleting repo ${params.owner}/${params.repo}...`); await this.githubApi.repos.delete(params); - process.stdout.write(' done.'); + console.log('\t...done.'); } catch (err) { - if (err.status == 404) process.stdout.write(' not found.'); + if (err.status == 404) console.log(' not found.'); else console.error(`\n\tSomething went wrong: ${err}.`); } try { - process.stdout.write(`Creating repo ${params.owner}/${params.repo}...`); + console.log(`Creating repo ${params.owner}/${params.repo}...`); await this.githubApi.repos.createForAuthenticatedUser({ name: this.githubRepo, }); - process.stdout.write(' done.'); + console.log('\t...done.'); } catch (err) { console.error(`\n\tSomething went wrong: ${err}.`); } From 722e6f2893bbb71e25e2f9dfed289124486aa10b Mon Sep 17 00:00:00 2001 From: Miguel de Benito Delgado Date: Sun, 16 Jan 2022 11:06:09 +0100 Subject: [PATCH 7/8] Make created repo private by default --- README.md | 2 +- src/githubHelper.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b204dfd..2e316c4 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ What is the name of the new repo #### github.recreateRepo -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. +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. This is useful when debugging this tool or a specific migration. You will always be prompted for confirmation. diff --git a/src/githubHelper.ts b/src/githubHelper.ts index c537e8a..418f07f 100644 --- a/src/githubHelper.ts +++ b/src/githubHelper.ts @@ -1282,6 +1282,7 @@ export class GithubHelper { console.log(`Creating repo ${params.owner}/${params.repo}...`); await this.githubApi.repos.createForAuthenticatedUser({ name: this.githubRepo, + private: true, }); console.log('\t...done.'); } catch (err) { From 8c9a977ef8bbf12190c12a4e268db577aa7ab1b2 Mon Sep 17 00:00:00 2001 From: Miguel de Benito Date: Sun, 16 Jan 2022 11:11:59 +0100 Subject: [PATCH 8/8] Sleep after repo creation --- src/githubHelper.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/githubHelper.ts b/src/githubHelper.ts index 418f07f..b0dc9d8 100644 --- a/src/githubHelper.ts +++ b/src/githubHelper.ts @@ -1288,5 +1288,6 @@ export class GithubHelper { } catch (err) { console.error(`\n\tSomething went wrong: ${err}.`); } + await utils.sleep(this.delayInMs); } }