diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 064991b226..c8d4b0ddeb 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -106,7 +106,7 @@ jobs: echo "::set-output name=release_version::$RELEASE_VERSION" - run: | npm ci - export NPM_TAG=$RELEASE_VERSION + export NPM_TAG=$(node index.js get-tag) npm publish --tag $NPM_TAG working-directory: ./dist/npm env: diff --git a/dist/npm/bin/devspace b/dist/npm/bin/devspace index 01896cc826..0b21f29a4e 100644 --- a/dist/npm/bin/devspace +++ b/dist/npm/bin/devspace @@ -35,6 +35,9 @@ if [ ! -f "$BINARY" ] || [ "$STAT" -lt 10000 ]; then echo "Running: node $BASEDIR/$INDEX_FILE finish-install $BINDIR" /usr/bin/env node "$BASEDIR/$INDEX_FILE" finish-install $BINDIR; + if [ $? -ne 0 ]; then + exit 1 + fi CMD_BIN=$(command -v cmd.exe) diff --git a/dist/npm/index.js b/dist/npm/index.js index 91cb11f235..104dddf3a2 100644 --- a/dist/npm/index.js +++ b/dist/npm/index.js @@ -8,7 +8,7 @@ const inquirer = require('inquirer'); const findProcess = require('find-process'); const downloadPathTemplate = - "https://github.com/loft-sh/devspace/releases/download/v{{version}}/devspace-{{platform}}-{{arch}}"; + "https://github.com/loft-sh/devspace/releases/download/{{version}}/devspace-{{platform}}-{{arch}}"; const ARCH_MAPPING = { ia32: "386", x64: "amd64", @@ -25,11 +25,11 @@ const PLATFORM_MAPPING = { }; if ( - !(process.platform in PLATFORM_MAPPING) || - !(process.arch in ARCH_MAPPING) + !(process.platform in PLATFORM_MAPPING) || + !(process.arch in ARCH_MAPPING) ) { console.error( - "Installation is not supported for this platform (" + + "Installation is not supported for this platform (" + process.platform + ") or architecture (" + process.arch + @@ -46,7 +46,7 @@ if (process.argv && process.argv.length > 2) { return; } -if (action == "noop") { +if (action === "noop") { console.log("Successfully ran noop command"); process.exit(0); } @@ -66,13 +66,13 @@ const getLatestVersion = function(callback, includePreReleases) { const releasesURL = "https://github.com/loft-sh/devspace/releases"; request({ uri: releasesURL, headers: requestHeaders }, function( - err, - res, - releasePage + err, + res, + releasePage ) { - if (res.statusCode != 200) { + if (res.statusCode !== 200) { console.error( - "Error requesting URL " + + "Error requesting URL " + releasesURL + " (Status Code: " + res.statusCode + @@ -81,19 +81,19 @@ const getLatestVersion = function(callback, includePreReleases) { console.error(err); process.exit(1); } - let versionRegex = - /^.*?\/loft-sh\/devspace\/releases\/download\/v([^\/-]*)\/devspace-.*$/s; + let versionRegex = + /^.*?\/loft-sh\/devspace\/releases\/download\/v([^\/-]*)\/devspace-.*$/s; if (includePreReleases) { - versionRegex = - /^.*?\/loft-sh\/devspace\/releases\/download\/v([^\/]*)\/devspace-.*$/s; + versionRegex = + /^.*?\/loft-sh\/devspace\/releases\/download\/v([^\/]*)\/devspace-.*$/s; } - + const latestVersion = releasePage.replace(versionRegex, - "$1" + "$1" ); - if (releasePage != latestVersion && latestVersion) { + if (releasePage !== latestVersion && latestVersion) { callback(latestVersion); } else { console.error("Unable to identify latest devspace version"); @@ -102,28 +102,24 @@ const getLatestVersion = function(callback, includePreReleases) { }); }; -if (action == "update-version") { - getLatestVersion(function(latestVersion) { - packageJson.version = latestVersion; - - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4)); +if (action === "update-version") { + packageJson.version = "" + process.env.RELEASE_VERSION; - process.exit(0); - }, true); + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4)); + process.exit(0); return; } -if (action == "get-tag") { - getLatestVersion(function(latestVersion) { - let tagRegex = /^.*-([a-z]*)(\.)?([0-9]*)?$/i - let tag = "latest" - - if (latestVersion.match(tagRegex)) { - tag = latestVersion.replace(tagRegex, "$1") - } - process.stdout.write(tag); - process.exit(0); - }, true); +if (action === "get-tag") { + let latestVersion = "" + process.env.RELEASE_VERSION; + let tagRegex = /^.*-([a-z]*)(\.)?([0-9]*)?$/i + let tag = "latest" + + if (latestVersion.match(tagRegex)) { + tag = latestVersion.replace(tagRegex, "$1") + } + process.stdout.write(tag); + process.exit(0); return; } @@ -134,15 +130,15 @@ if (action == "get-tag") { */ function rimraf(dir_path) { if (fs.existsSync(dir_path)) { - fs.readdirSync(dir_path).forEach(function(entry) { - var entry_path = path.join(dir_path, entry); - if (fs.lstatSync(entry_path).isDirectory()) { - rimraf(entry_path); - } else { - fs.unlinkSync(entry_path); - } - }); - fs.rmdirSync(dir_path); + fs.readdirSync(dir_path).forEach(function(entry) { + let entry_path = path.join(dir_path, entry); + if (fs.lstatSync(entry_path).isDirectory()) { + rimraf(entry_path); + } else { + fs.unlinkSync(entry_path); + } + }); + fs.rmdirSync(dir_path); } } @@ -153,7 +149,7 @@ let continueProcess = function(askRemoveGlobalFolder) { let downloadExtension = ".dl"; let binaryName = packageJson.name; - if (platform == PLATFORM_MAPPING.win32) { + if (platform === PLATFORM_MAPPING.win32) { binaryName += ".exe"; } @@ -175,7 +171,7 @@ let continueProcess = function(askRemoveGlobalFolder) { if (process.argv.length > 3 && fs.existsSync(normalizePath(process.argv[3]))) { globalDir = normalizePath(process.argv[3]); dotBinDir = normalizePath(path.join(globalDir, "..", "..", ".bin")); - + if (fs.existsSync(normalizePath(path.join(dotBinDir, "devspace")))) { globalDir = normalizePath(dotBinDir); } @@ -184,7 +180,7 @@ let continueProcess = function(askRemoveGlobalFolder) { try { let yarnGlobalDir = normalizePath(path.join(execSync('yarn global dir').toString(), "node_modules")); let yarnLink = normalizePath(path.join(yarnGlobalDir, packageJson.name)); - let yarnLinkExists = fs.existsSync(yarnLink) && yarnLink == packageDir; + let yarnLinkExists = fs.existsSync(yarnLink) && yarnLink === packageDir; if (yarnLinkExists || packageDir.startsWith(yarnGlobalDir)) { try { @@ -199,7 +195,7 @@ let continueProcess = function(askRemoveGlobalFolder) { try { let npmGlobalDir = normalizePath(execSync('npm root -g').toString()); let npmLink = normalizePath(path.join(npmGlobalDir, packageJson.name)); - let npmLinkExists = fs.existsSync(npmLink) && npmLink == packageDir; + let npmLinkExists = fs.existsSync(npmLink) && npmLink === packageDir; if (npmLinkExists || !globalDir || packageDir.startsWith(npmGlobalDir)) { try { @@ -210,19 +206,19 @@ let continueProcess = function(askRemoveGlobalFolder) { } } } catch(e) {} - - if (globalDir == null) { - if (platform == PLATFORM_MAPPING.win32) { + + if (globalDir === null) { + if (platform === PLATFORM_MAPPING.win32) { console.error("Error finding binary installation directory"); process.exit(3); } globalDir = fallbackGlobalDir; } - + try { fs.mkdirSync(globalDir, { recursive: true }); } catch(e) {} - + let binaryPath = path.join(globalDir, binaryName); if (process.argv.length > 3 && fs.existsSync(normalizePath(process.argv[3]))) { let binaryDir = normalizePath(process.argv[3]); @@ -241,24 +237,24 @@ let continueProcess = function(askRemoveGlobalFolder) { } catch (e) {} let removeScripts = function(allScripts) { - if (platform == PLATFORM_MAPPING.win32) { + if (platform === PLATFORM_MAPPING.win32) { if (allScripts) { try { fs.unlinkSync(binaryPath.replace(/\.exe$/i, "")); } catch (e) {} } - + // Remove bin/devspace.ps1 file because it can cause issues try { fs.unlinkSync(binaryPath.replace(/\.exe$/i, ".ps1")); } catch (e) {} } } - - if (action == "install") { + + if (action === "install") { removeScripts(false); - if (platform == PLATFORM_MAPPING.win32) { + if (platform === PLATFORM_MAPPING.win32) { if (globalInstall) { // Remove bin/devspace.cmd file because it can cause issues try { @@ -272,7 +268,7 @@ let continueProcess = function(askRemoveGlobalFolder) { } } } - else if (action == "uninstall") { + else if (action === "uninstall") { try { fs.unlinkSync(binaryPath); } catch (e) {} @@ -285,7 +281,7 @@ let continueProcess = function(askRemoveGlobalFolder) { try { fs.unlinkSync(binaryPath.replace(/\.exe$/i, ".cmd")); } catch (e) {} - + removeScripts(true); if (askRemoveGlobalFolder && process.stdout.isTTY) { @@ -299,44 +295,44 @@ let continueProcess = function(askRemoveGlobalFolder) { }; inquirer - .prompt([ - { - type: "list", - name: "checkRemoveGlobalFolder", - message: "Do you want to remove the global DevSpace config folder ~/.devspace?", - choices: ["no", "yes"], - }, - ]) - .then(answers => { - if (answers.checkRemoveGlobalFolder == "yes") { - removeGlobalFolder(); - } - }); + .prompt([ + { + type: "list", + name: "checkRemoveGlobalFolder", + message: "Do you want to remove the global DevSpace config folder ~/.devspace?", + choices: ["no", "yes"], + }, + ]) + .then(answers => { + if (answers.checkRemoveGlobalFolder === "yes") { + removeGlobalFolder(); + } + }); } else { console.warn("DevSpace will not remove the global ~/.devspace folder without asking. This uninstall call is being executed in a non-interactive environment.") } } else { - if (action == "finish-install") { + if (action === "finish-install") { cleanPathVar = process.env.PATH.replace(/(^|;)[a-z]:/gi, path.delimiter).replace(/(\\)+/g, '/'); cleanGlobalDir = globalDir.replace(/(^|;)[a-z]:/gi, '').replace(/(\\)+/g, '/').trimRight("/"); - - if (cleanPathVar.split(path.delimiter).indexOf(cleanGlobalDir) == -1 && cleanPathVar.split(path.delimiter).indexOf(cleanGlobalDir + "/") == -1) { + + if (cleanPathVar.split(path.delimiter).indexOf(cleanGlobalDir) === -1 && cleanPathVar.split(path.delimiter).indexOf(cleanGlobalDir + "/") === -1) { console.error("\n\n################################################\nWARNING: npm binary directory NOT in $PATH environment variable: " + globalDir + "\n################################################\n\n"); - + if (globalInstall) { process.exit(4) } } - const showRootError = function() { + const showRootError = function(version) { console.error("\n############################################"); console.error( - "Failed to download DevSpace CLI due to permission issues!\n" + "Failed to download DevSpace CLI due to permission issues!\n" ); console.error("There are two options to fix this:"); - console.error("1. Do not run 'npm install' as root (recommended)"); + console.error("1. Run this command once: 'sudo devspace'"); console.error( - "2. Run this command: npm install --unsafe-perm=true -g devspace" + "2. Run this command: 'sudo npm uninstall -g devspace && npm install --unsafe-perm=true -g devspace@"+version+"'" ); console.error(" You may need to run this command using sudo."); console.error("############################################\n"); @@ -345,97 +341,96 @@ let continueProcess = function(askRemoveGlobalFolder) { const downloadRelease = function(version) { let downloadPath = downloadPathTemplate - .replace("{{version}}", version) - .replace("{{platform}}", platform) - .replace("{{arch}}", arch); + .replace("{{version}}", version) + .replace("{{platform}}", platform) + .replace("{{arch}}", arch); - if (platform == PLATFORM_MAPPING.win32) { + if (platform === PLATFORM_MAPPING.win32) { downloadPath += ".exe"; } console.log("Download DevSpace CLI release: " + downloadPath + "\n"); const spinner = new Spinner( - "%s Downloading DevSpace CLI... (this may take a minute)" + "%s Downloading DevSpace CLI... (this may take a minute)" ); spinner.setSpinnerString("|/-\\"); spinner.start(); let writeStream = fs - .createWriteStream(binaryPath + downloadExtension) - .on("error", function(err) { - spinner.stop(true); - console.error("Unable to write stream: " + err) - showRootError(); - }); + .createWriteStream(binaryPath + downloadExtension) + .on("error", function(err) { + spinner.stop(true); + console.error("Unable to write stream: " + err) + showRootError(version); + }); request({ uri: downloadPath, headers: requestHeaders, encoding: null }) - .on("error", function() { - spinner.stop(true); - console.error("Error requesting URL: " + downloadPath); - process.exit(6); - }) - .on("response", function(res) { - if (res.statusCode != 200) { - writeStream.end(); + .on("error", function() { spinner.stop(true); - - if (res.statusCode == 404) { - console.error("Release version " + version + " not found.\n"); - - getLatestVersion(function(latestVersion) { - if (latestVersion != version) { - console.log( - "Downloading latest stable release instead. Latest version is: " + - latestVersion + - "\n" - ); - - downloadRelease(latestVersion); - } - }); - return; + console.error("Error requesting URL: " + downloadPath); + process.exit(6); + }) + .on("response", function(res) { + if (res.statusCode !== 200) { + writeStream.end(); + spinner.stop(true); + + if (res.statusCode === 404) { + console.error("Release version " + version + " not found.\n"); + + getLatestVersion(function(latestVersion) { + if (latestVersion !== version) { + console.log( + "Downloading latest stable release instead. Latest version is: " + + latestVersion + + "\n" + ); + + downloadRelease(latestVersion); + } + }); + } else { + console.error( + "Error requesting URL " + + downloadPath + + " (Status Code: " + + res.statusCode + + ")" + ); + console.error(err); + process.exit(7); + } } else { - console.error( - "Error requesting URL " + - downloadPath + - " (Status Code: " + - res.statusCode + - ")" - ); - console.error(err); - process.exit(7); + try { + res.pipe(writeStream); + } catch (e) { + console.error("Unable to write stream: " + e) + showRootError(version); + } } - } else { + }) + .on("end", function() { + writeStream.end(); + spinner.stop(true); + try { - res.pipe(writeStream); + fs.chmodSync(binaryPath + downloadExtension, "0755"); } catch (e) { - console.error("Unable to write stream: " + e) - showRootError(); + console.error("Unable to chmod: " + e) + showRootError(version); } - } - }) - .on("end", function() { - writeStream.end(); - spinner.stop(true); - - try { - fs.chmodSync(binaryPath + downloadExtension, 0755); - } catch (e) { - console.error("Unable to chmod: " + e) - showRootError(); - } - try { - fs.renameSync(binaryPath + downloadExtension, binaryPath); - } catch (e) { - console.log(e); - console.error("\nRenaming release binary failed. Please copy file manually:\n from: " + binaryPath + downloadExtension + "\n to: " + binaryPath + "\n"); - process.exit(8); - } + try { + fs.renameSync(binaryPath + downloadExtension, binaryPath); + } catch (e) { + console.log(e); + console.error("\nRenaming release binary failed. Please copy file manually:\n from: " + binaryPath + downloadExtension + "\n to: " + binaryPath + "\n"); + process.exit(8); + } - removeScripts(true); - }); + removeScripts(true); + }); }; downloadRelease(version); @@ -445,24 +440,24 @@ let continueProcess = function(askRemoveGlobalFolder) { if (process.ppid > 1) { findProcess('pid', process.ppid) - .then(function (list) { - if (list.length == 1 && list[0].ppid > 1) { - findProcess('pid', list[0].ppid) - .then(function (list) { - if (list.length == 1 && /((npm-cli.js("|')\s+up(date)?)|(yarn.js("|')\s+(global\s+)?upgrade))\s+.*((\/)|(\\)|(\s))devspace((\/)|(\\)|(\s)|$)/.test(list[0].cmd)) { - continueProcess(false); - } else { - continueProcess(true); - } - }, function () { - continueProcess(true); - }) - } else { + .then(function (list) { + if (list.length === 1 && list[0].ppid > 1) { + findProcess('pid', list[0].ppid) + .then(function (list) { + if (list.length === 1 && /((npm-cli.js("|')\s+up(date)?)|(yarn.js("|')\s+(global\s+)?upgrade))\s+.*((\/)|(\\)|(\s))devspace((\/)|(\\)|(\s)|$)/.test(list[0].cmd)) { + continueProcess(false); + } else { + continueProcess(true); + } + }, function () { + continueProcess(true); + }) + } else { + continueProcess(true); + } + }, function () { continueProcess(true); - } - }, function () { - continueProcess(true); - }) + }) } else { continueProcess(true); -} +} \ No newline at end of file