From b648fdeef83cb07e4f73c543205b737f5ba51f87 Mon Sep 17 00:00:00 2001 From: Yuncheng Date: Sun, 26 Feb 2023 14:39:53 +1100 Subject: [PATCH 1/5] changed the exec and added os matrix in assert test --- .github/workflows/stackql-assert.yml | 5 ++++- lib/tests/utils.test.js | 33 +++++++++++++--------------- lib/utils.js | 9 ++++---- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/.github/workflows/stackql-assert.yml b/.github/workflows/stackql-assert.yml index 368c0f2..edd9594 100644 --- a/.github/workflows/stackql-assert.yml +++ b/.github/workflows/stackql-assert.yml @@ -7,7 +7,10 @@ on: pull_request: jobs: stackql-exec-google-example: - runs-on: ubuntu-latest + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{matrix.os}} name: 'Assert test ' steps: diff --git a/lib/tests/utils.test.js b/lib/tests/utils.test.js index 03ec29b..2975423 100644 --- a/lib/tests/utils.test.js +++ b/lib/tests/utils.test.js @@ -1,8 +1,12 @@ const { setupAuth, executeStackql } = require("../utils"); +const childProcess = require("child_process"); + +jest.mock("child_process", () => ({ + exec: jest.fn(), +})); describe("util", () => { let core; - let exec; const expectedAuth = '{ "google": { "type": "service_account", "credentialsfilepath": "sa-key.json" }}' beforeEach(() => { @@ -98,7 +102,7 @@ describe("util", () => { process.env.QUERY = undefined; process.env.QUERY_FILE_PATH = undefined; - await executeStackql(core, exec); + await executeStackql(core); expect(core.setFailed).toBeCalledWith( "Either test_query or test_query_file_path need to be set" @@ -109,7 +113,7 @@ describe("util", () => { process.env = { ...EXECUTE_ENV }; process.env.AUTH = undefined; - await executeStackql(core, exec); + await executeStackql(core); expect(core.setFailed).toHaveBeenCalledWith("Cannot find AUTH environment variable when executing stackql"); }); @@ -118,29 +122,22 @@ describe("util", () => { process.env = { ...EXECUTE_ENV }; process.env.QUERY = undefined; - await executeStackql(core, exec); + await executeStackql(core); - expect(exec.exec).toHaveBeenCalledWith("stackql", [ - "exec", - "-i", - "test-query.json", - "--auth=test-auth", - "--output=json", - ]); + expect(childProcess.exec).toHaveBeenCalledWith( + "stackql exec -i test-query.json --auth=test-auth --output=json" + ); }); it("should execute stackql with query", async () => { process.env = { ...EXECUTE_ENV }; process.env.QUERY_FILE_PATH = undefined; - await executeStackql(core, exec); + await executeStackql(core); - expect(exec.exec).toHaveBeenCalledWith("stackql", [ - "exec", - "test", - "--auth=test-auth", - "--output=json", - ]); + expect(childProcess.exec).toHaveBeenCalledWith( + "stackql exec test --auth=test-auth --output=json" + ); }); }); }); diff --git a/lib/utils.js b/lib/utils.js index b93cb3d..517056d 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,4 @@ +const { exec } = require("child_process"); function setupAuth(core) { const fs = require("fs"); let auth; @@ -27,7 +28,7 @@ function setupAuth(core) { core.exportVariable("AUTH", auth); } -async function executeStackql(core, exec) { +async function executeStackql(core) { if (!checkEnvVarValid(process.env.AUTH)) { core.setFailed("Cannot find AUTH environment variable when executing stackql"); return; @@ -61,7 +62,7 @@ async function executeStackql(core, exec) { } try { - await exec.exec("stackql", args); + await exec(`stackql ${args.join(" ")}`); } catch (error) { core.error(error); core.setFailed("Error when executing stackql"); @@ -73,9 +74,7 @@ async function executeStackql(core, exec) { * @param {*} variable */ const checkEnvVarValid = (variable) => { - if (!variable || variable === "" || variable === "undefined") { - return false; - } + if (!variable || variable === "" || variable === "undefined") return false; return true; }; From fe1955ecfb7e9646a0076c9959bff257647575d6 Mon Sep 17 00:00:00 2001 From: Yuncheng Date: Sun, 26 Feb 2023 14:43:21 +1100 Subject: [PATCH 2/5] remove exec from action.yml; --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 6e910ee..ecd9746 100644 --- a/action.yml +++ b/action.yml @@ -61,7 +61,7 @@ runs: with: script: | const {executeStackql} = require('./lib/utils.js') - await executeStackql(core, exec) + await executeStackql(core) env: QUERY_FILE_PATH: ${{ inputs.test_query_file_path }} QUERY: ${{inputs.test_query}} From 442b4310946a3b93c5d354c10c19e6959dcced41 Mon Sep 17 00:00:00 2001 From: Yuncheng Date: Sun, 26 Feb 2023 19:23:56 +1100 Subject: [PATCH 3/5] migrate the two steps execute --- action.yml | 15 ++++++--- lib/tests/utils.test.js | 70 +++++++++++++++++++---------------------- lib/utils.js | 22 +++++++------ 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/action.yml b/action.yml index ecd9746..c81ed0d 100644 --- a/action.yml +++ b/action.yml @@ -1,4 +1,4 @@ -name: 'StackQL Studios - stackql-assert' +name: 'StackQL Studios - StackQL Assert' description: 'run StackQL query to test and audit your infrastructure.' author: 'Yuncheng Yang, StackQL Studios' inputs: @@ -55,18 +55,23 @@ runs: AUTH_FILE_PATH: ${{ inputs.auth_obj_path }} AUTH_STR: ${{inputs.auth_str}} - - name: Execute query - id: exec-query + - name: get stackql command uses: actions/github-script@v6 with: script: | - const {executeStackql} = require('./lib/utils.js') - await executeStackql(core) + const {getStackqlCommand} = require('./lib/utils.js') + getStackqlCommand(core) env: QUERY_FILE_PATH: ${{ inputs.test_query_file_path }} QUERY: ${{inputs.test_query}} OUTPUT: 'json' + - name: execute stackql command + id: exec-stackql + shell: bash + run: | + ${{ env.STACKQL_COMMAND }} + - name: Check results uses: actions/github-script@v6 with: diff --git a/lib/tests/utils.test.js b/lib/tests/utils.test.js index 2975423..404458d 100644 --- a/lib/tests/utils.test.js +++ b/lib/tests/utils.test.js @@ -1,13 +1,9 @@ -const { setupAuth, executeStackql } = require("../utils"); -const childProcess = require("child_process"); - -jest.mock("child_process", () => ({ - exec: jest.fn(), -})); +const { setupAuth, getStackqlCommand, setOutput } = require("../utils"); describe("util", () => { let core; - const expectedAuth = '{ "google": { "type": "service_account", "credentialsfilepath": "sa-key.json" }}' + const expectedAuth = + '{ "google": { "type": "service_account", "credentialsfilepath": "sa-key.json" }}'; beforeEach(() => { core = { @@ -22,10 +18,6 @@ describe("util", () => { console.error(message); }), }; - - exec = { - exec: jest.fn().mockResolvedValue(true), - }; }); describe("setupAuth", () => { @@ -34,7 +26,6 @@ describe("util", () => { AUTH_FILE_PATH: "./lib/tests/test-auth.json", }; - beforeEach(() => { jest.resetModules(); process.env = { ...AUTH_ENV }; @@ -47,41 +38,41 @@ describe("util", () => { it("should throw error when neither AUTH_STR or AUTH_FILE_PATH is set", () => { process.env.AUTH_STR = undefined; process.env.AUTH_FILE_PATH = undefined; - - setupAuth(core) + + setupAuth(core); expect(core.setFailed).toBeCalledWith( "Either AUTH_FILE_PATH or AUTH_STR must be set." ); }); it("should set AUTH environment variable when AUTH_STR is set", () => { - process.env.AUTH_FILE_PATH = undefined; + process.env.AUTH_FILE_PATH = undefined; + + setupAuth(core); - setupAuth(core); - - expect(core.exportVariable).toBeCalledWith("AUTH", expectedAuth); + expect(core.exportVariable).toBeCalledWith("AUTH", expectedAuth); }); it("should set AUTH environment variable when AUTH_FILE_PATH is set", () => { - process.env.AUTH_STR = undefined; - - setupAuth(core); - - expect(core.exportVariable).toBeCalledWith("AUTH", expectedAuth); + process.env.AUTH_STR = undefined; + + setupAuth(core); + + expect(core.exportVariable).toBeCalledWith("AUTH", expectedAuth); }); it("should throw error when AUTH_FILE_PATH is set but file does not exist", () => { process.env.AUTH_STR = undefined; process.env.AUTH_FILE_PATH = "./failed-test-auth.json"; - - setupAuth(core) + + setupAuth(core); expect(core.setFailed).toBeCalledWith( `Cannot find auth file ${process.env.AUTH_FILE_PATH}` ); }); }); - describe("executeStackql", () => { + describe("getStackqlCommand", () => { const EXECUTE_ENV = { QUERY: "test", QUERY_FILE_PATH: "test-query.json", @@ -95,37 +86,40 @@ describe("util", () => { afterEach(() => { process.env = EXECUTE_ENV; + jest.clearAllMocks(); }); it("should return error when there is neither query or query file path", async () => { process.env = { ...EXECUTE_ENV }; process.env.QUERY = undefined; process.env.QUERY_FILE_PATH = undefined; - - await executeStackql(core); + + getStackqlCommand(core); expect(core.setFailed).toBeCalledWith( - "Either test_query or test_query_file_path need to be set" + "Either query or query_file_path need to be set" ); }); - it("should return error when there is no AUTH", async() => { + it("should return error when there is no AUTH", async () => { process.env = { ...EXECUTE_ENV }; process.env.AUTH = undefined; - await executeStackql(core); + getStackqlCommand(core); - expect(core.setFailed).toHaveBeenCalledWith("Cannot find AUTH environment variable when executing stackql"); + expect(core.setFailed).toHaveBeenCalledWith( + "Cannot find AUTH environment variable when executing stackql" + ); }); it("should execute stackql with query file path", async () => { process.env = { ...EXECUTE_ENV }; process.env.QUERY = undefined; - await executeStackql(core); + getStackqlCommand(core); - expect(childProcess.exec).toHaveBeenCalledWith( - "stackql exec -i test-query.json --auth=test-auth --output=json" + expect(core.exportVariable).toBeCalledWith( + "STACKQL_COMMAND", "stackql exec -i test-query.json --auth='test-auth' --output='json'" ); }); @@ -133,10 +127,10 @@ describe("util", () => { process.env = { ...EXECUTE_ENV }; process.env.QUERY_FILE_PATH = undefined; - await executeStackql(core); + getStackqlCommand(core); - expect(childProcess.exec).toHaveBeenCalledWith( - "stackql exec test --auth=test-auth --output=json" + expect(core.exportVariable).toBeCalledWith( + "STACKQL_COMMAND", "stackql exec \"test\" --auth='test-auth' --output='json'" ); }); }); diff --git a/lib/utils.js b/lib/utils.js index 517056d..9e94b23 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,4 @@ -const { exec } = require("child_process"); + function setupAuth(core) { const fs = require("fs"); let auth; @@ -28,7 +28,8 @@ function setupAuth(core) { core.exportVariable("AUTH", auth); } -async function executeStackql(core) { +async function getStackqlCommand(core) { + if (!checkEnvVarValid(process.env.AUTH)) { core.setFailed("Cannot find AUTH environment variable when executing stackql"); return; @@ -43,7 +44,7 @@ async function executeStackql(core) { if (!checkEnvVarValid(query) && !checkEnvVarValid(queryFilePath)) { - core.setFailed("Either test_query or test_query_file_path need to be set"); + core.setFailed("Either query or query_file_path need to be set"); return; } @@ -53,16 +54,15 @@ async function executeStackql(core) { "exec", "-i", queryFilePath, - "--auth=" + auth, - "--output=" + output, + `--auth='${auth}'`, + `--output='${output}'` ]; } if (query) { - args = ["exec", query, "--auth=" + auth, "--output=" + output]; + args = ["exec", `"${query}"`, `--auth='${auth}'`, `--output='${output}'`]; } - try { - await exec(`stackql ${args.join(" ")}`); + core.exportVariable('STACKQL_COMMAND', `stackql ${args.join(" ")}`) } catch (error) { core.error(error); core.setFailed("Error when executing stackql"); @@ -74,11 +74,13 @@ async function executeStackql(core) { * @param {*} variable */ const checkEnvVarValid = (variable) => { - if (!variable || variable === "" || variable === "undefined") return false; + if (!variable || variable === "" || variable === "undefined") { + return false; + } return true; }; module.exports = { setupAuth, - executeStackql, + getStackqlCommand, }; From 17a174ca13c6a03d49d706ffcd431251d3e0b9b1 Mon Sep 17 00:00:00 2001 From: Yuncheng Date: Sun, 26 Feb 2023 19:29:29 +1100 Subject: [PATCH 4/5] fix var name --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index c81ed0d..10fb424 100644 --- a/action.yml +++ b/action.yml @@ -67,7 +67,7 @@ runs: OUTPUT: 'json' - name: execute stackql command - id: exec-stackql + id: exec-query shell: bash run: | ${{ env.STACKQL_COMMAND }} From b0c3661ff37bd6279355ae5a2a7acfa2158294ad Mon Sep 17 00:00:00 2001 From: Yuncheng Date: Sun, 26 Feb 2023 21:11:48 +1100 Subject: [PATCH 5/5] fix creds prep --- .github/workflows/stackql-assert.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/stackql-assert.yml b/.github/workflows/stackql-assert.yml index edd9594..a4b2152 100644 --- a/.github/workflows/stackql-assert.yml +++ b/.github/workflows/stackql-assert.yml @@ -18,7 +18,18 @@ jobs: uses: actions/checkout@v3 + - name: Prep Google Creds (Windows) + if: ${{ matrix.os == 'windows-latest'}} + run: | ## use the secret to create json file + $GoogleCreds = [System.Environment]::GetEnvironmentVariable("GOOGLE_CREDS_ENV") + $GoogleCredsDecoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($GoogleCreds)) + Write-Output $GoogleCredsDecoded | Set-Content sa-key.json + shell: pwsh + env: + GOOGLE_CREDS_ENV: ${{ secrets.GOOGLE_CREDS }} + - name: Prep Google Creds (bash) + if: ${{ matrix.os != 'windows-latest' }} shell: bash run: | ## use the base64 encoded secret to create json file sudo echo ${{ secrets.GOOGLE_CREDS }} | base64 -d > sa-key.json