|
#!/usr/bin/env /usr/local/bin/node |
|
// jshint asi:true |
|
// jshint esversion: 11 |
|
// jshint module:true |
|
// jshint node:true |
|
|
|
/** |
|
Before running this script make sure all the tags for the releases are pushed to the GitHub repository as they were in Gitlab |
|
*/ |
|
|
|
import childProcess from "child_process"; |
|
import fs from "fs"; |
|
import path from "path"; |
|
|
|
const { Octokit } = await installAndRequire("octokit"); |
|
const { Gitlab } = await installAndRequire("@gitbeaker/node"); |
|
|
|
const octokit = new Octokit({ |
|
userAgent: "node " + process.version, |
|
auth: process.env.GITHUB_TOKEN, |
|
}); |
|
const gitbeaker = new Gitlab({ token: process.env.GITLAB_TOKEN }); |
|
|
|
const gitlabRepositoryId = process.env.GITLAB_REPO; |
|
|
|
if (!gitlabRepositoryId) { |
|
throw new Error( |
|
`"GITLAB_REPO" env var is required and set to the id as retrieved from gitlab settings page` |
|
); |
|
} |
|
|
|
const githubOwnerRepo = process.env.GITHUB_REPO || ""; |
|
const [githubOwner, githubRepo] = githubOwnerRepo.split("/"); |
|
if (!githubOwner || !githubRepo) { |
|
throw new Error( |
|
`Valid "GITHUB_REPO" env var is required of the format "owner/project", '${githubOwnerRepo}' was passed` |
|
); |
|
} |
|
const gitlabProject = await gitbeaker.Projects.show(gitlabRepositoryId); |
|
const existingReleases = await gitbeaker.Releases.all(gitlabRepositoryId); |
|
|
|
existingReleases.forEach(async ({ name, tag_name, description }) => { |
|
console.log("uploading", name); |
|
await octokit.request("POST /repos/{owner}/{repo}/releases", { |
|
owner: githubOwner, |
|
repo: githubRepo, |
|
tag_name: tag_name, |
|
name: name, |
|
body: mapLinks(description), |
|
}); |
|
}); |
|
|
|
function mapLinks(gitlabMarkdown) { |
|
const linkRegexp = new RegExp( |
|
`(\\[[^\\]]+\\])(?:\\(${gitlabProject.web_url |
|
.replace("/", "\\/") |
|
.replace(".", "\\.")}(?:\\/-\\/)?)([^\\)]*)\\)`, |
|
"ig" |
|
); |
|
return gitlabMarkdown.replace( |
|
linkRegexp, |
|
(match, displayText, commitSlug) => |
|
`${displayText}(https://github.com/${githubOwnerRepo}${commitSlug})` |
|
); |
|
} |
|
|
|
/** |
|
* Sets up the ability to require global node packages. |
|
* |
|
* @return {object} Returns the required node package object |
|
*/ |
|
async function globalRequire(packageName) { |
|
const env = Object.assign({}, process.env); |
|
env.PATH = path.resolve("/usr/local/bin") + ":" + env.PATH; |
|
|
|
const globalNodeModulesDir = |
|
childProcess |
|
.execSync(npmBin() + " root -g", { env: env }) |
|
.toString() |
|
.trim() + "/"; |
|
let packageDir = path.join(globalNodeModulesDir, packageName, "/"); |
|
|
|
//find package required by older versions of npm |
|
if (!fs.existsSync(packageDir)) { |
|
packageDir = path.join( |
|
globalNodeModulesDir, |
|
"npm/node_modules/", |
|
packageName |
|
); |
|
} |
|
|
|
// Package not found |
|
if (!fs.existsSync(packageDir)) { |
|
throw new Error("Cannot find global module '" + packageName + "'"); |
|
} |
|
|
|
const packageMeta = JSON.parse( |
|
fs.readFileSync(path.join(packageDir, "package.json")).toString() |
|
); |
|
const main = path.join(packageDir, packageMeta.main || packageMeta.files[0]); |
|
|
|
return await import(main); |
|
} |
|
|
|
async function installAndRequire(module) { |
|
try { |
|
return await import(module); |
|
} catch (e) { |
|
try { |
|
return await globalRequire(module); |
|
} catch (e) { |
|
installModule(module); |
|
|
|
// Not catching error if one is thrown. |
|
return await globalRequire(module); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Installs node module if it doesn't exit.) |
|
*/ |
|
function installModule(module) { |
|
// Allows one to run the npm command as if on the command line. |
|
const execSync = childProcess.execSync; |
|
|
|
const env = Object.assign({}, process.env); |
|
env.PATH = path.resolve("/usr/local/bin") + ":" + env.PATH; |
|
|
|
// Get the path to npm bin |
|
const npm = npmBin(); |
|
|
|
// The install command |
|
const cmd = npm + " install -g " + module; |
|
|
|
console.log("Installing the " + module + " Node module..."); |
|
|
|
execSync(cmd, { |
|
cwd: process.cwd(), |
|
env: env, |
|
}) |
|
.toString("utf8") |
|
.trim(); |
|
|
|
console.log("Installation complete."); |
|
} |
|
|
|
/** |
|
* Gets the path to your npm executable. |
|
* |
|
* @return {string} The full path to your npm executable |
|
*/ |
|
function npmBin() { |
|
const execSync = childProcess.execSync; |
|
const env = Object.assign({}, process.env); |
|
env.PATH = path.resolve("/usr/local/bin") + ":" + env.PATH; |
|
|
|
// Get the path to npm bin |
|
return execSync("which npm", { env: env }).toString("utf8").trim(); |
|
} |