diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 2a3d621..2b13f67 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -40,9 +40,15 @@ jobs: run: npm ci - name: 'Test' - run: | - npm test -- --reporter json --reporter-options output=${{ runner.temp }}/report-${{ matrix.os }}.json - cat ${{ runner.temp }}/report-${{ matrix.os }}.json | jq + env: + LC_ALL: 'en_US.UTF-8' + LANG: 'en_US.UTF-8' + run: npm test -- --reporter json --reporter-options output=${{ runner.temp }}/report-${{ matrix.os }}.json + + - name: 'Print Tests' + # run this step even if previous step failed + if: (success() || failure()) + run: cat ${{ runner.temp }}/report-${{ matrix.os }}.json | jq - name: 'Publish Tests' uses: 'dorny/test-reporter@v1' diff --git a/dist/index.js b/dist/index.js index 78dd22b..45b193a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -211,7 +211,9 @@ exports.addPath = addPath; * @returns string */ function getInput(name, options) { + const key = `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + console.log('core/getInput', { key, val }); if (options && options.required && !val) { throw new Error(`Input required and not supplied: ${name}`); } @@ -533,8 +535,8 @@ class OidcClient { const res = yield httpclient .getJson(id_token_url) .catch(error => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n Error Message: ${error.result.message}`); }); const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; @@ -2036,6 +2038,7 @@ const core = __nccwpck_require__(186); * @returns {Input} */ const getInput = () => { + console.log('envenv:', process.env); const customArguments = getInput.core.getInput('arguments'); const additionalPluginPaths = getInput.core.getInput('additional-plugin-paths') @@ -2075,7 +2078,7 @@ const makensis = __nccwpck_require__(598); */ const isDirectoryAsync = async (item) => { const stats = await fs.stat(item); - + return stats.isDirectory(); }; @@ -2089,7 +2092,7 @@ const fileExistsAsync = async (item) => { } catch (err) { return false; } - + return true; } @@ -2191,7 +2194,7 @@ class Installer { args.push('-V1'); } } - + args.push(this.customArguments); args.push(`"${path.resolve(scriptPath)}"`); @@ -2214,7 +2217,7 @@ class Installer { } const nsisPluginPath = path.join(nsisdir, 'Plugins'); this.debugLog(`Using system Plugins path ${nsisPluginPath}`); - + const copies = this.pluginPaths.map(pluginPath => { console.log('Including plugin path', pluginPath); return copyDirectoryAsync(pluginPath, nsisPluginPath); @@ -2319,14 +2322,14 @@ class Makensis { */ async getSymbolsAsync() { const buffer = await this.execAsync('-HDRINFO'); - + // Look for the defined symbols in the output. const exp = /Defined symbols: (.*)/g; const matches = exp.exec(buffer.toString('utf-8')); if (!matches || !matches.length || matches.length < 2) { throw new Error('Unable to get symbols'); } - + // Create a map of all of the symbols. const symbols = { }; @@ -2482,7 +2485,7 @@ module.exports = require("util"); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; -/******/ +/******/ /******/ // The require function /******/ function __nccwpck_require__(moduleId) { /******/ // Check if module is in cache @@ -2496,7 +2499,7 @@ module.exports = require("util"); /******/ // no module.loaded needed /******/ exports: {} /******/ }; -/******/ +/******/ /******/ // Execute the module function /******/ var threw = true; /******/ try { @@ -2505,16 +2508,16 @@ module.exports = require("util"); /******/ } finally { /******/ if(threw) delete __webpack_module_cache__[moduleId]; /******/ } -/******/ +/******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } -/******/ +/******/ /************************************************************************/ /******/ /* webpack/runtime/compat */ -/******/ +/******/ /******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/"; -/******/ +/******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be in strict mode. @@ -2572,4 +2575,4 @@ run(); module.exports = __webpack_exports__; /******/ })() -; \ No newline at end of file +; diff --git a/package.json b/package.json index 6e296dc..9e0c1a6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "dist/index.js", "scripts": { "build": "ncc build -o dist src/index.js", - "test": "mocha --reporter spec --timeout 5000" + "test": "mocha --reporter spec --timeout 5000 test/**.spec.js" }, "repository": { "type": "git", diff --git a/test/bootstrap.js b/test/bootstrap.js new file mode 100644 index 0000000..89308fe --- /dev/null +++ b/test/bootstrap.js @@ -0,0 +1,16 @@ +'use strict'; + +const args = process.argv.splice(2); +for (let i = 0; i < args.length; i += 2) { + const key = args[i]; + const value = args[i + 1]; + if (!value) { + console.warn('missing arg value for', key); + continue; + } + + console.log('assigning arg to env', key, value); + process.env[key] = value; +} + +require('../dist'); diff --git a/test/e2e.spec.js b/test/e2e.spec.js new file mode 100644 index 0000000..97e4a9b --- /dev/null +++ b/test/e2e.spec.js @@ -0,0 +1,120 @@ +'use strict'; + +const assert = require('assert'); +const { exec } = require('child_process'); +const { access, unlink } = require('fs/promises'); +const path = require('path'); + +const exists = async (path) => { + try { + await access(path); + return true; + } + catch { + return false; + } +}; + +/** + * @param {string} path + */ +const unlinkIfExistsAsync = async (path) => { + if (await exists(path)) { + unlink(path); + } +}; + +describe('e2e', () => { + before(async () => { + const promises = ['./basic.exe', './with-plugins.exe'] + .map(unlinkIfExistsAsync); + + await Promise.all(promises); + }); + + /** + * @typedef {{ + * customArguments?: string, + * additionalPluginPaths?: string[], + * scriptFile?: string, + * }} RunOptions + * @param {RunOptions} options + */ + const run = async (options = {}) => { + const { + customArguments, + additionalPluginPaths, + scriptFile + } = options; + + const args = []; + const env = { + PATH: process.env.PATH, + debug: 'true', + }; + if (customArguments) { + args.push('INPUT_ARGUMENTS', customArguments); + } + if (additionalPluginPaths && additionalPluginPaths.length) { + args.push('INPUT_ADDITIONAL-PLUGIN-PATHS', additionalPluginPaths.join('\n')); + } + if (scriptFile) { + args.push('INPUT_SCRIPT-FILE', scriptFile); + } + + const programPath = require.resolve('./bootstrap'); + const testDir = path.dirname(programPath); + const cwd = path.join(testDir, '../'); + console.log('paths', { + programPath, + testDir, + cwd + }); + const promise = new Promise((resolve, reject) => { + exec(`node ${programPath} ${args.join(' ')}`, { + env, + cwd, + }, (error, stdout, stderr) => { + console.log('cwd', cwd); + console.log('stdout', stdout); + console.log('stderr', stderr); + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + + await promise; + }; + + /** + * @param {string} script + * @param {(options: RunOptions) => void} fn + */ + const test = (script, fn) => { + it(`should create installer for ${script}.nsi`, async () => { + const options = { + scriptFile: `./test/${script}.nsi` + }; + if (fn) { + fn(options); + } + + await run(options); + + const actual = await exists(`./test/${script}.exe`); + + assert( + actual, + `Installer \`./test/${script}.exe\` should exist` + ); + }); + }; + + test('basic'); + test('with-plugins', options => options.additionalPluginPaths = [ + './test/EnVar' + ]); +});