diff --git a/.github/workflows/stackql-exec-test.yml b/.github/workflows/stackql-exec-test.yml index 23e78c3..472d472 100644 --- a/.github/workflows/stackql-exec-test.yml +++ b/.github/workflows/stackql-exec-test.yml @@ -114,6 +114,21 @@ jobs: GOOGLE_PROJECT: ${{ vars.GOOGLE_PROJECT }} GOOGLE_ZONE: ${{ vars.GOOGLE_ZONE }} + # + # run a query using the `query_file_path`, `data_file_path` and `vars` inputs (dry-run) + # + - name: google query example with query file and data file using vars (dry-run) + id: stackql-query-file-with-data-file-and-vars-dry-run + uses: ./ + with: + query_file_path: './stackql_scripts/google-instances-by-status-with-external-data-file.iql' + data_file_path: './stackql_scripts/google-instances-by-status-with-external-data-file.jsonnet' + vars: GOOGLE_PROJECT=${{ env.GOOGLE_PROJECT }},GOOGLE_ZONE=${{ env.GOOGLE_ZONE }} + dry_run: true + env: + GOOGLE_PROJECT: ${{ vars.GOOGLE_PROJECT }} + GOOGLE_ZONE: ${{ vars.GOOGLE_ZONE }} + # # run a query using the `query_file_path`, `data_file_path` and `vars` inputs # diff --git a/README.md b/README.md index 0b80b71..3129bba 100644 --- a/README.md +++ b/README.md @@ -7,21 +7,24 @@ Github Action as a wrapper for executing a single command in stackql, maps all s Authentication to StackQL providers is done via environment variables source from GitHub Actions Secrets. To learn more about authentication, see the setup instructions for your provider or providers at the [StackQL Provider Registry Docs](https://stackql.io/registry). ## Inputs -- `query` - stackql query to execute **(need to supply either `query` or `query_file_path`)** -- `query_file_path` - stackql query file to execute **(need to supply either `query` or `query_file_path`)** -- `data_file_path` - (optional) path to data file to pass to the stackql query preprocessor (`json` or `jsonnet`) -- `vars` - (optional) comma delimited list of variables to pass to the stackql query preprocessor (supported with `jsonnet` config blocks or `jsonnet` data files only), accepts `var1=val1,var2=val2`, can be used to source environment variables into stackql queries -- `query_output` - (optional) output format of the stackql exec result, accepts `table`, `csv`, `json` and `text`, defaults to `json` -- `auth_obj_path` - (optional) the path of json file that stores stackql AUTH string **(only required when using non-standard environment variable names)** -- `auth_str` - (optional) stackql AUTH string **(only required when using non-standard environment variable names)** -- `is_command` - (optional defaults to 'false') set to true if the stackql execution is a command that does not return data +- **`query`** - stackql query to execute *(need to supply either __`query`__ or __`query_file_path`__)* +- **`query_file_path`** - stackql query file to execute *(need to supply either __`query`__ or __`query_file_path`__)* +- **`data_file_path`** - (optional) path to data file to pass to the stackql query preprocessor (`json` or `jsonnet`) +- **`dry_run`** - (optional) set to `true` to print the query that would be executed without actually executing it (default is `false`) +- **`vars`** - (optional) comma delimited list of variables to pass to the stackql query preprocessor (supported with `jsonnet` config blocks or `jsonnet` data files only), accepts `var1=val1,var2=val2`, can be used to source environment variables into stackql queries +- **`query_output`** - (optional) output format of the stackql exec result, accepts `table`, `csv`, `json` and `text`, defaults to `json` +- **`auth_obj_path`** - (optional) the path of json file that stores stackql AUTH string *(only required when using non-standard environment variable names)* +- **`auth_str`** - (optional) stackql AUTH string *(only required when using non-standard environment variable names)* +- **`is_command`** - (optional) set to `true` if the stackql execution is a command that does not return data (defaults to `false`) +- **`on_failure`** - (optional) behavior on a failure in query, supported values are `exit` (default) and `continue` ## Outputs This action uses [setup-stackql](https://github.com/marketplace/actions/stackql-studio-setup-stackql), with use_wrapper set to `true`, `stdout` and `stderr` are set to `exec-result` and `exec-error` -- `exec-result` - The STDOUT stream of the call to the `stackql` binary. -- `exec-error` - The STDERR stream of the call to the `stackql` binary. +- **`stackql-query-results`** - results from a stackql query (in the format specified) +- **`stackql-command-output`** - text output from a stackql command (a query that does not return data) +- **`stackql-query-error`** - error from a stackql query ## Examples diff --git a/action.yml b/action.yml index f1e430d..51eac96 100644 --- a/action.yml +++ b/action.yml @@ -11,6 +11,10 @@ inputs: data_file_path: description: jsonnet or json data file to be passed to query preprocessor required: false + dry_run: + description: set to true to print the query that would be executed without actually executing it (default is false) + required: false + default: 'false' vars: description: comma delimited list of vars to be passed to query preprocessor (supported with jsonnet config blocks or jsonnet data files only) required: false @@ -91,6 +95,7 @@ runs: QUERY_FILE_PATH: ${{ inputs.query_file_path }} QUERY: ${{inputs.query}} DATA_FILE_PATH: ${{inputs.data_file_path}} + DRY_RUN: ${{inputs.dry_run}} OUTPUT: ${{inputs.query_output}} VARS: ${{inputs.vars}} @@ -103,9 +108,10 @@ runs: const utilsPath = path.join(process.env.GITHUB_ACTION_PATH, 'lib', 'utils.js') const {execStackQLQuery} = require(utilsPath); const onFailure = process.env.ON_FAILURE || 'exit'; // default to 'exit' if not specified - await execStackQLQuery(core, process.env.STACKQL_COMMAND, process.env.IS_COMMAND === 'true', onFailure); + await execStackQLQuery(core, process.env.STACKQL_COMMAND, process.env.IS_COMMAND === 'true', onFailure, process.env.DRY_RUN === 'true'); env: IS_COMMAND: ${{ inputs.is_command }} + DRY_RUN: ${{ inputs.dry_run }} ON_FAILURE: ${{ inputs.on_failure }} branding: diff --git a/lib/utils.js b/lib/utils.js index 65a5c3b..bc78ee9 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -38,9 +38,10 @@ function setupAuth(core) { async function getStackqlCommand(core) { - const [query, queryFilePath, auth, output = "json", vars, dataFilePath] = [ + const [query, queryFilePath, dry_run, auth, output = "json", vars, dataFilePath] = [ process.env.QUERY, process.env.QUERY_FILE_PATH, + process.env.DRY_RUN, process.env.AUTH, process.env.OUTPUT, process.env.VARS, @@ -94,6 +95,12 @@ async function getStackqlCommand(core) { args.push(`--output ${output}`); + if (checkEnvVarValid(dry_run)) { + if(dry_run === "true"){ + args.push(`--dryrun`); + } + } + if (checkEnvVarValid(auth)) { args.push(`--auth "${auth}"`); } @@ -124,16 +131,22 @@ const checkEnvVarValid = (variable) => { * @param {string} command - The StackQL command to be executed. * @param {boolean} isCommand - Indicates if the operation is a command (true) or query (false). * @param {string} onFailure - The action to take if the command fails. Either 'exit' or 'continue'. + * @param {boolean} dryRun - Indicates if the operation is a dry run only. */ -async function execStackQLQuery(core, command, isCommand, onFailure) { - - if (onFailure !== 'exit' && onFailure !== 'continue') { - core.setFailed(`onFailure must be 'exit' or 'continue'. Received: ${onFailure}`); - return; +async function execStackQLQuery(core, command, isCommand, onFailure, dryRun) { + + if (dryRun) { + // dry run + core.info(`dry-run enabled, skipping stackql query execution`); + } else { + // real query + if (onFailure !== 'exit' && onFailure !== 'continue') { + core.setFailed(`onFailure must be 'exit' or 'continue'. Received: ${onFailure}`); + return; + } + core.info(`executing stackql query (isCommand: ${isCommand}): ${command}`); } - core.info(`executing stackql query (isCommand: ${isCommand}): ${command}`); - try { let { stdout, stderr } = await execAsync(command); @@ -156,7 +169,12 @@ async function execStackQLQuery(core, command, isCommand, onFailure) { core.debug(`STDOUT: ${stdout}`); if (!isCommand) { core.setOutput('stackql-query-results', stdout); - core.info(`query output:\n${stdout}`); + if(dryRun){ + const json = JSON.parse(stdout); + core.info(`dry-run query:\n${json[0].query}`); + } else { + core.info(`query output:\n${stdout}`); + } } } else { core.debug('STDOUT: ');