From 58218c18c90ae6b5a310ccca7e8fdff008552172 Mon Sep 17 00:00:00 2001 From: Nathan Pierce Date: Thu, 18 Jun 2020 14:34:17 -0400 Subject: [PATCH] Fixing bad failure logic + tests --- .github/workflows/failure-tests.yml | 43 +++++++++ .github/workflows/functional-tests.yml | 2 +- dist/index.js | 117 +++++++++++++------------ execute.js | 6 +- execute.test.js | 7 +- index.js | 99 +++++++++++---------- 6 files changed, 164 insertions(+), 110 deletions(-) create mode 100644 .github/workflows/failure-tests.yml diff --git a/.github/workflows/failure-tests.yml b/.github/workflows/failure-tests.yml new file mode 100644 index 0000000..3b206ee --- /dev/null +++ b/.github/workflows/failure-tests.yml @@ -0,0 +1,43 @@ +name: Failure Tests +on: + push: + branches: [ master, release/* ] + +jobs: + + one: + runs-on: [self-hosted, macOS] + steps: + - name: command failure + id: command-failure + uses: ./ + with: + anka-template: "10.15.4" + anka-tag: "base" + anka-run-options: "-n" + commands: "java -version" + two: + runs-on: [self-hosted, macOS] + steps: + - name: bad host command option + id: bad-host-command-option + uses: ./ + with: + anka-template: "10.15.4" + anka-tag: "base" + anka-run-options: "-n" + host-command-options: "1231!!" + commands: "echo 123" + three: + runs-on: [self-hosted, macOS] + steps: + - name: multi-line commands failure + id: multi-line-commands-failure + uses: ./ + with: + anka-template: "10.15.4" + anka-tag: "base" + anka-run-options: "-n" + commands: | + echo 123 + java -version \ No newline at end of file diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index b1238ae..5c4c0f9 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -17,7 +17,7 @@ jobs: anka-template: "10.15.4" anka-tag: "base" anka-run-options: "-n" - commands: "echo 123" + commands: "echo \"123\"" functional-tests: runs-on: [self-hosted, macOS] diff --git a/dist/index.js b/dist/index.js index 8f0ed64..ef4cc5f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1029,7 +1029,11 @@ async function nodeCommands(commands,hostCommandOptions,existingSTD) { } } // Execute - await exec.exec('bash', ['-c', commands], options); + try { + await exec.exec('bash', ['-c', commands], options); + } catch(error) { + throw new Error(`nodeCommands exec.exec\n${error.stack}`) + } // Return STD outputs exports.STD = STD; exports.finalHostCommandOptions = options; // used in tests @@ -2048,64 +2052,63 @@ const ankaTemplate = core.getInput('anka-template'); const lockFileLocation = core.getInput('lock-file-location'); async function run() { - - const ankaTag = core.getInput('anka-tag'); - const ankaVMLabel = await helpers.getVMLabel(ankaCustomVMLabel) - - const ankaCommands = core.getInput('commands'); - const hostPreCommands = core.getInput('host-pre-commands'); - const hostPostCommands = core.getInput('host-post-commands'); - - const ankaStartOptions = core.getInput('anka-start-options'); - const ankaRunOptions = core.getInput('anka-run-options'); - const ankaRegistryPullOptions = core.getInput('anka-registry-pull-options'); - - const filesToArtifact = core.getInput('artifact-files'); - const artifactArchiveFileName = core.getInput('artifact-archive-file-name'); - const artifactRootDirectory = core.getInput('artifacts-root-directory'); - - const skipRegistryPull = core.getInput('skip-registry-pull'); - - const ankaVirtCLIPath = await io.which('anka', true) - console.log(`Anka Virtualization CLI found at: ${ankaVirtCLIPath}`); - if (ankaTemplate.length === 0) { - throw new Error('anka-template is required in your workflow definition!'); - } - // Execution ========= - if (hostPreCommands) { - await execute.nodeCommands(hostPreCommands,hostCommandOptions,execute.STD) - } - /// Prepare VM - //// Pull from Registry - await prepare.ankaRegistryPull(ankaTemplate,ankaTag,ankaRegistryPullOptions,hostCommandOptions,lockFileLocation,skipRegistryPull); - //// Clone from template - await prepare.ankaClone(ankaTemplate,ankaVMLabel,hostCommandOptions,lockFileLocation); - //// Start the VM - await prepare.ankaStart(ankaVMLabel,ankaStartOptions,hostCommandOptions); - /// Run commands inside VM - console.log(`Running commands inside of Anka VM ==============\nAnka run options: ${ankaRunOptions}\n${ankaCommands}\n==============\n`) - await execute.ankaRun(ankaVMLabel,ankaRunOptions,ankaCommands,hostCommandOptions); - if (hostPostCommands) { - await execute.nodeCommands(hostPostCommands,hostCommandOptions,execute.STD); - } - if (filesToArtifact) { // No artifacts, no problem! - await prepare.uploadArtifacts(artifactArchiveFileName,filesToArtifact,artifactRootDirectory,hostCommandOptions) - } - core.setOutput('std', execute.STD); - /// Cleanup - helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) -} - -try { - // We use GITHUB_ACTION in the ENV to prevent other steps from using isPost when they didn't really fail. - if (process.env[`${process.env['GITHUB_ACTION']}_isPost`] === 'true') { + try { + const ankaTag = core.getInput('anka-tag'); + const ankaVMLabel = await helpers.getVMLabel(ankaCustomVMLabel) + + const ankaCommands = core.getInput('commands'); + const hostPreCommands = core.getInput('host-pre-commands'); + const hostPostCommands = core.getInput('host-post-commands'); + + const ankaStartOptions = core.getInput('anka-start-options'); + const ankaRunOptions = core.getInput('anka-run-options'); + const ankaRegistryPullOptions = core.getInput('anka-registry-pull-options'); + + const filesToArtifact = core.getInput('artifact-files'); + const artifactArchiveFileName = core.getInput('artifact-archive-file-name'); + const artifactRootDirectory = core.getInput('artifacts-root-directory'); + + const skipRegistryPull = core.getInput('skip-registry-pull'); + + const ankaVirtCLIPath = await io.which('anka', true) + console.log(`Anka Virtualization CLI found at: ${ankaVirtCLIPath}`); + if (ankaTemplate.length === 0) { + throw new Error('anka-template is required in your workflow definition!'); + } + // Execution ========= + if (hostPreCommands) { + await execute.nodeCommands(hostPreCommands,hostCommandOptions,execute.STD) + } + /// Prepare VM + //// Pull from Registry + await prepare.ankaRegistryPull(ankaTemplate,ankaTag,ankaRegistryPullOptions,hostCommandOptions,lockFileLocation,skipRegistryPull); + //// Clone from template + await prepare.ankaClone(ankaTemplate,ankaVMLabel,hostCommandOptions,lockFileLocation); + //// Start the VM + await prepare.ankaStart(ankaVMLabel,ankaStartOptions,hostCommandOptions); + /// Run commands inside VM + console.log(`Running commands inside of Anka VM ==============\nAnka run options: ${ankaRunOptions}\n${ankaCommands}\n==============\n`) + await execute.ankaRun(ankaVMLabel,ankaRunOptions,ankaCommands,hostCommandOptions); + if (hostPostCommands) { + await execute.nodeCommands(hostPostCommands,hostCommandOptions,execute.STD); + } + if (filesToArtifact) { // No artifacts, no problem! + await prepare.uploadArtifacts(artifactArchiveFileName,filesToArtifact,artifactRootDirectory,hostCommandOptions) + } + core.setOutput('std', execute.STD); + /// Cleanup helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) - } else { - core.exportVariable(`${process.env['GITHUB_ACTION']}_isPost`, true); - run() + } catch (error) { + core.setFailed(`${error.stack}`); } -} catch (error) { - core.setFailed(error.stack); +} + +// We use GITHUB_ACTION in the ENV to prevent other steps from using isPost when they didn't really fail. +if (process.env[`${process.env['GITHUB_ACTION']}_isPost`] === 'true') { + helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) +} else { + core.exportVariable(`${process.env['GITHUB_ACTION']}_isPost`, true); + run() } diff --git a/execute.js b/execute.js index 91bd6c7..4e1bb4b 100644 --- a/execute.js +++ b/execute.js @@ -30,7 +30,11 @@ async function nodeCommands(commands,hostCommandOptions,existingSTD) { } } // Execute - await exec.exec('bash', ['-c', commands], options); + try { + await exec.exec('bash', ['-c', commands], options); + } catch(error) { + throw new Error(`nodeCommands exec.exec\n${error.stack}`) + } // Return STD outputs exports.STD = STD; exports.finalHostCommandOptions = options; // used in tests diff --git a/execute.test.js b/execute.test.js index 0a2c9c1..c6283b6 100644 --- a/execute.test.js +++ b/execute.test.js @@ -2,12 +2,17 @@ let execute = require('./execute'); describe('execute functions', () => { - let options = "{ silent: true }" + let options = "{ silent: false }" describe('nodeCommands', () => { test('basic', async() => { await execute.nodeCommands("echo 123",options) await expect(`${execute.STD.trim()}`).toBe("123"); }); + test('fail with bad command option', async() => { + await expect( + execute.nodeCommands("java --version",options) + ).rejects.toThrowError(/failed with exit code 1/) + }); test('fail with single quotes', async() => { await expect( execute.nodeCommands("echo 123","{ cwd: './' }") diff --git a/index.js b/index.js index 73dd2ad..78f29a3 100644 --- a/index.js +++ b/index.js @@ -11,62 +11,61 @@ const ankaTemplate = core.getInput('anka-template'); const lockFileLocation = core.getInput('lock-file-location'); async function run() { + try { + const ankaTag = core.getInput('anka-tag'); + const ankaVMLabel = await helpers.getVMLabel(ankaCustomVMLabel) - const ankaTag = core.getInput('anka-tag'); - const ankaVMLabel = await helpers.getVMLabel(ankaCustomVMLabel) + const ankaCommands = core.getInput('commands'); + const hostPreCommands = core.getInput('host-pre-commands'); + const hostPostCommands = core.getInput('host-post-commands'); - const ankaCommands = core.getInput('commands'); - const hostPreCommands = core.getInput('host-pre-commands'); - const hostPostCommands = core.getInput('host-post-commands'); + const ankaStartOptions = core.getInput('anka-start-options'); + const ankaRunOptions = core.getInput('anka-run-options'); + const ankaRegistryPullOptions = core.getInput('anka-registry-pull-options'); - const ankaStartOptions = core.getInput('anka-start-options'); - const ankaRunOptions = core.getInput('anka-run-options'); - const ankaRegistryPullOptions = core.getInput('anka-registry-pull-options'); + const filesToArtifact = core.getInput('artifact-files'); + const artifactArchiveFileName = core.getInput('artifact-archive-file-name'); + const artifactRootDirectory = core.getInput('artifacts-root-directory'); - const filesToArtifact = core.getInput('artifact-files'); - const artifactArchiveFileName = core.getInput('artifact-archive-file-name'); - const artifactRootDirectory = core.getInput('artifacts-root-directory'); + const skipRegistryPull = core.getInput('skip-registry-pull'); - const skipRegistryPull = core.getInput('skip-registry-pull'); - - const ankaVirtCLIPath = await io.which('anka', true) - console.log(`Anka Virtualization CLI found at: ${ankaVirtCLIPath}`); - if (ankaTemplate.length === 0) { - throw new Error('anka-template is required in your workflow definition!'); - } - // Execution ========= - if (hostPreCommands) { - await execute.nodeCommands(hostPreCommands,hostCommandOptions,execute.STD) - } - /// Prepare VM - //// Pull from Registry - await prepare.ankaRegistryPull(ankaTemplate,ankaTag,ankaRegistryPullOptions,hostCommandOptions,lockFileLocation,skipRegistryPull); - //// Clone from template - await prepare.ankaClone(ankaTemplate,ankaVMLabel,hostCommandOptions,lockFileLocation); - //// Start the VM - await prepare.ankaStart(ankaVMLabel,ankaStartOptions,hostCommandOptions); - /// Run commands inside VM - console.log(`Running commands inside of Anka VM ==============\nAnka run options: ${ankaRunOptions}\n${ankaCommands}\n==============\n`) - await execute.ankaRun(ankaVMLabel,ankaRunOptions,ankaCommands,hostCommandOptions); - if (hostPostCommands) { - await execute.nodeCommands(hostPostCommands,hostCommandOptions,execute.STD); - } - if (filesToArtifact) { // No artifacts, no problem! - await prepare.uploadArtifacts(artifactArchiveFileName,filesToArtifact,artifactRootDirectory,hostCommandOptions) + const ankaVirtCLIPath = await io.which('anka', true) + console.log(`Anka Virtualization CLI found at: ${ankaVirtCLIPath}`); + if (ankaTemplate.length === 0) { + throw new Error('anka-template is required in your workflow definition!'); + } + // Execution ========= + if (hostPreCommands) { + await execute.nodeCommands(hostPreCommands,hostCommandOptions,execute.STD) + } + /// Prepare VM + //// Pull from Registry + await prepare.ankaRegistryPull(ankaTemplate,ankaTag,ankaRegistryPullOptions,hostCommandOptions,lockFileLocation,skipRegistryPull); + //// Clone from template + await prepare.ankaClone(ankaTemplate,ankaVMLabel,hostCommandOptions,lockFileLocation); + //// Start the VM + await prepare.ankaStart(ankaVMLabel,ankaStartOptions,hostCommandOptions); + /// Run commands inside VM + console.log(`Running commands inside of Anka VM ==============\nAnka run options: ${ankaRunOptions}\n${ankaCommands}\n==============\n`) + await execute.ankaRun(ankaVMLabel,ankaRunOptions,ankaCommands,hostCommandOptions); + if (hostPostCommands) { + await execute.nodeCommands(hostPostCommands,hostCommandOptions,execute.STD); + } + if (filesToArtifact) { // No artifacts, no problem! + await prepare.uploadArtifacts(artifactArchiveFileName,filesToArtifact,artifactRootDirectory,hostCommandOptions) + } + core.setOutput('std', execute.STD); + /// Cleanup + helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) + } catch (error) { + core.setFailed(`${error.stack}`); } - core.setOutput('std', execute.STD); - /// Cleanup - helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) } -try { - // We use GITHUB_ACTION in the ENV to prevent other steps from using isPost when they didn't really fail. - if (process.env[`${process.env['GITHUB_ACTION']}_isPost`] === 'true') { - helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) - } else { - core.exportVariable(`${process.env['GITHUB_ACTION']}_isPost`, true); - run() - } -} catch (error) { - core.setFailed(error.stack); +// We use GITHUB_ACTION in the ENV to prevent other steps from using isPost when they didn't really fail. +if (process.env[`${process.env['GITHUB_ACTION']}_isPost`] === 'true') { + helpers.cleanup(ankaCustomVMLabel,hostCommandOptions,ankaTemplate,lockFileLocation) +} else { + core.exportVariable(`${process.env['GITHUB_ACTION']}_isPost`, true); + run() }