Skip to content

Commit 5c4f30c

Browse files
authored
Merge pull request #21 from stackql/feature/refactor
made auth optional, added support for data files and vars
2 parents fbc9f45 + 43531df commit 5c4f30c

13 files changed

+234
-173
lines changed

.github/workflows/stackql-assert.yml

+38-45
Original file line numberDiff line numberDiff line change
@@ -17,65 +17,58 @@ jobs:
1717
- name: Checkout
1818
uses: actions/checkout@v3
1919

20-
21-
- name: Prep Google Creds (Windows)
22-
if: ${{ matrix.os == 'windows-latest'}}
23-
run: | ## use the secret to create json file
24-
$GoogleCreds = [System.Environment]::GetEnvironmentVariable("GOOGLE_CREDS_ENV")
25-
$GoogleCredsDecoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($GoogleCreds))
26-
Write-Output $GoogleCredsDecoded | Set-Content sa-key.json
27-
shell: pwsh
28-
env:
29-
GOOGLE_CREDS_ENV: ${{ secrets.GOOGLE_CREDS }}
30-
31-
- name: Prep Google Creds (bash)
32-
if: ${{ matrix.os != 'windows-latest' }}
33-
shell: bash
34-
run: | ## use the base64 encoded secret to create json file
35-
sudo echo ${{ secrets.GOOGLE_CREDS }} | base64 -d > sa-key.json
36-
37-
- name: Use test query string and expected results string with auth object
20+
#
21+
# Example `test_query` with `expected_rows`
22+
#
23+
- name: Use test query string and expected rows
3824
uses: ./
3925
with:
40-
auth_obj_path: './.github/workflows/workflow_scripts/auth.json'
4126
test_query: |
42-
REGISTRY PULL google v23.01.00116;
27+
REGISTRY PULL google;
4328
SELECT name
4429
FROM google.compute.instances
4530
WHERE project = 'stackql-demo' AND zone = 'australia-southeast1-a' AND name = 'stackql-demo-001';
46-
expected_results_str: ' [{"name":"stackql-demo-001"}]'
31+
expected_rows: 1
32+
env:
33+
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
4734

48-
- name: Use test query file and expected result string with auth object
35+
#
36+
# Example `test_query_file_path` with `expected_results_str`
37+
#
38+
- name: Use test query file and expected result string
4939
uses: ./
5040
with:
51-
auth_obj_path: './.github/workflows/workflow_scripts/auth.json'
5241
test_query_file_path: './.github/workflows/workflow_scripts/google-example.iql'
53-
expected_results_str: ' [{"name":"stackql-demo-001"}]'
54-
55-
- name: Use test query string and expected results string, with auth string
56-
uses: ./
57-
with:
58-
auth_str: '{ "google": { "type": "service_account", "credentialsfilepath": "sa-key.json" }}'
59-
test_query: |
60-
REGISTRY PULL google v23.01.00116;
61-
SELECT name
62-
FROM google.compute.instances
63-
WHERE project = 'stackql-demo' AND zone = 'australia-southeast1-a' AND name = 'stackql-demo-001';
6442
expected_results_str: '[{"name":"stackql-demo-001"}]'
43+
env:
44+
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
6545

66-
- name: Use test query string and expected results file, with auth object
46+
#
47+
# Example `test_query_file_path` with `expected_results_file_path` supplying `vars` using an inline `jsonnet` config block
48+
#
49+
- name: Use test query file and expected results file path using inline jsonnet config block and external vars
6750
uses: ./
6851
with:
69-
auth_obj_path: './.github/workflows/workflow_scripts/auth.json'
70-
test_query_file_path: './.github/workflows/workflow_scripts/google-example.iql'
71-
expected_results_str: '[{"name":"stackql-demo-001"}]'
52+
test_query_file_path: './.github/workflows/workflow_scripts/google-example-inline-jsonnet.iql'
53+
expected_results_file_path: './.github/workflows/workflow_scripts/google-example-inline-jsonnet-results.json'
54+
vars: GOOGLE_PROJECT=${{ env.GOOGLE_PROJECT }},GOOGLE_ZONE=${{ env.GOOGLE_ZONE }}
55+
env:
56+
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
57+
GOOGLE_PROJECT: ${{ vars.GOOGLE_PROJECT }}
58+
GOOGLE_ZONE: ${{ vars.GOOGLE_ZONE }}
7259

73-
- name: Use test query string and expected rows, with auth object
60+
#
61+
# Example `test_query_file_path` with `expected_rows` supplying `vars` using `jsonnet` config provided using `data_file_path`
62+
#
63+
- name: Use test query string and expected results file, with auth object
7464
uses: ./
7565
with:
76-
auth_str: '{ "google": { "type": "service_account", "credentialsfilepath": "sa-key.json" }}'
77-
test_query_file_path: './.github/workflows/workflow_scripts/google-example.iql'
78-
expected_rows: 1
79-
80-
81-
66+
test_query_file_path: './.github/workflows/workflow_scripts/github-example.iql'
67+
data_file_path: './.github/workflows/workflow_scripts/github-example-data.jsonnet'
68+
vars: TEST_ORG=${{ env.TEST_ORG }},TEST_REPO=${{ env.TEST_REPO }}
69+
expected_rows: 1
70+
env:
71+
STACKQL_GITHUB_USERNAME: ${{ secrets.STACKQL_GITHUB_USERNAME }}
72+
STACKQL_GITHUB_PASSWORD: ${{ secrets.STACKQL_GITHUB_PASSWORD }}
73+
TEST_ORG: ${{ vars.TEST_ORG }}
74+
TEST_REPO: ${{ vars.TEST_REPO }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
local org = std.extVar("TEST_ORG");
2+
local repo = std.extVar("TEST_REPO");
3+
{
4+
org: org,
5+
repo: repo,
6+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
REGISTRY PULL github v23.01.00104;
2-
SHOW PROVIDERS;
3-
select total_private_repos
4-
from github.orgs.orgs
5-
where org = 'stackql';
1+
REGISTRY PULL github;
2+
SELECT name FROM github.repos.repos WHERE org = '{{ .org }}' AND name = '{{ .repo }}';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<<<jsonnet
2+
local project = std.extVar("GOOGLE_PROJECT");
3+
local zone = std.extVar("GOOGLE_ZONE");
4+
{
5+
project: project,
6+
zone: zone,
7+
}
8+
>>>
9+
SELECT name
10+
FROM google.compute.instances
11+
WHERE project = '{{ .project }}' and zone = '{{ .zone }}' and name = 'stackql-demo-001';
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
REGISTRY PULL google v23.01.00116;
21
SELECT name
32
FROM google.compute.instances
43
WHERE project = 'stackql-demo' AND zone = 'australia-southeast1-a' AND name = 'stackql-demo-001';

.stackql/readline/readline.tmp

-7
This file was deleted.

README.md

+83-30
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,97 @@
11
# stackql-assert
22

3-
The `stackql/stackql-assert` action is an composite action that runs stackql query and check if result matches expected result
4-
3+
The `stackql/stackql-assert` action is an composite action that runs a `stackql` query and checks if the result matches an expected result
54

65
# Usage
76

8-
## AUTH
9-
> **Note**
10-
> stackql-assert action uses same auth setup as [stackql-exec](https://github.com/stackql/stackql-exec/blob/main/README.md).
11-
> [Learn more](https://stackql.io/docs/getting-started/authenticating) about authentication setup when running stackql
7+
## Provider Authentication
8+
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).
129

13-
### Example auth string
14-
```
15-
{ "google": { "type": "service_account", "credentialsfilepath": "sa-key.json" },
16-
"github": { "type": "basic", "credentialsenvvar": "STACKQL_GITHUB_CREDS" }}
17-
```
18-
It can be passed with `auth_str` as a string, or stored in a file and pass filename to `auth-obj-path`
19-
- For "basic" auth, you need to set a environment variable with same name as the value of `credentialsenvvar` in the auth string for the Github Action step. You can use [Github Secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) to store the value of the environment variable, and use env to pass it to the action. For example:
20-
```
21-
env:
22-
STACKQL_GITHUB_CREDS: ${{ secrets.STACKQL_GITHUB_CREDS }}
23-
```
24-
- For "service_account" auth, you need to store the credentials into a file; You can follow the example of `Prep Google Creds (bash)` step in the [example workflow](./.github/workflows/stackql-assert.yml)
10+
## Inputs
11+
- `test_query` - stackql query to execute **(need to supply either `test_query` or `test_query_file_path`)**
12+
- `test_query_file_path` - stackql query file to execute **(need to supply either `test_query` or `test_query_file_path`)**
13+
- `data_file_path` - (optional) path to data file to pass to the stackql query preprocessor (`json` or `jsonnet`)
14+
- `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
15+
- `expected_rows` - (optional) Expected number of rows in the result.
16+
- `expected_results_str` - (optional) Expected result (`json`) from executing test query, support object string (overrides `expected_results_file_path`)
17+
- `expected_results_file_path` - (optional) Results file (`json`) that stores expected result, json is support
18+
- `auth_obj_path` - (optional) the path of json file that stores stackql AUTH string **(only required when using non-standard environment variable names)**
19+
- `auth_str` - (optional) stackql AUTH string **(only required when using non-standard environment variable names)**
20+
21+
**__NOTE:__ one of `expected_rows`, `expected_results_str` or `expected_results_file_path` is required**
2522

2623
## Test Query
27-
- Use `test_query` or `test_query_path` to pass the test query to the action. The test query should be a valid StackQL query. The action will run the query and check if the result is empty or not. If the result is empty, the action will fail the step.
28-
- Either `test_query` or `test_query_path` is required. If both are provided, `test_query` will be used.
24+
- Use `test_query` or `test_query_file_path` to pass the test query to the action. The test query should be a valid StackQL query. The action will run the query and check if the result is empty or not. If the result is empty, the action will fail the step.
25+
- Either `test_query` or `test_query_file_path` are required. If both are provided, `test_query` will be used.
2926
- query example can be found in [example workflow](./.github/workflows/stackql-assert.yml) and [example .iql file](./.github/workflows/workflow_scripts)
3027

3128
## Expected Result
32-
- Use `expected_results_str` or `expected_results_file_path` to pass the expected result to the action. The expected result should be a valid JSON object. The action will compare the result with the expected result. If the result is not the same as the expected result, the action will fail the step.
33-
- Either `expected_results_str` or `expected_results_file_path` is required. If both are provided, `expected_results_str` will be used.
29+
- Use `expected_results_str` or `expected_results_file_path` or `expected_rows` to pass the expected result to the action. The expected result (`expected_results_str` or `expected_results_file_path`) should be a valid `json` object. The action will compare the result with the expected result. If the result is not the same as the expected result, the action will fail the step.
30+
- Either `expected_results_str` or `expected_results_file_path` or `expected_rows` are required. If `expected_results_str` and `expected_results_file_path` are provided, `expected_results_str` will be used.
3431
- Expected result example can be found in [example workflow](./.github/workflows/stackql-assert.yml) and [example .json file](./.github/workflows/workflow_scripts)
3532

33+
## Examples
34+
The following excerpts from a GitHub Actions workflow demonstrate how to use the `stackql/stackql-assert` action.
35+
36+
## Example `test_query` with `expected_rows`
37+
38+
```yaml
39+
- name: Use test query string and expected rows
40+
uses: ./
41+
with:
42+
test_query: |
43+
REGISTRY PULL google;
44+
SELECT name
45+
FROM google.compute.instances
46+
WHERE project = 'stackql-demo' AND zone = 'australia-southeast1-a' AND name = 'stackql-demo-001';
47+
expected_rows: 1
48+
env:
49+
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
50+
```
51+
52+
## Example `test_query_file_path` with `expected_results_str`
53+
54+
```yaml
55+
- name: Use test query file and expected result string
56+
uses: ./
57+
with:
58+
test_query_file_path: './.github/workflows/workflow_scripts/google-example.iql'
59+
expected_results_str: '[{"name":"stackql-demo-001"}]'
60+
env:
61+
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
62+
```
63+
64+
## Example `test_query_file_path` with `expected_results_file_path` supplying `vars` using an inline `jsonnet` config block
65+
66+
```yaml
67+
- name: Use test query file and expected results file path using inline jsonnet config block and external vars
68+
uses: ./
69+
with:
70+
test_query_file_path: './.github/workflows/workflow_scripts/google-example-inline-jsonnet.iql'
71+
expected_results_file_path: './.github/workflows/workflow_scripts/google-example-inline-jsonnet-results.json'
72+
vars: GOOGLE_PROJECT=${{ env.GOOGLE_PROJECT }},GOOGLE_ZONE=${{ env.GOOGLE_ZONE }}
73+
env:
74+
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
75+
GOOGLE_PROJECT: ${{ vars.GOOGLE_PROJECT }}
76+
GOOGLE_ZONE: ${{ vars.GOOGLE_ZONE }}
77+
```
78+
79+
## Example `test_query_file_path` with `expected_rows` supplying `vars` using `jsonnet` config provided using `data_file_path`
80+
81+
```yaml
82+
- name: Use test query string and expected results file, with auth object
83+
uses: ./
84+
with:
85+
test_query_file_path: './.github/workflows/workflow_scripts/google-example.iql'
86+
data_file_path: './.github/workflows/workflow_scripts/google-example-data.jsonnet'
87+
vars: TEST_ORG=${{ env.TEST_ORG }},TEST_REPO=${{ env.TEST_REPO }}
88+
expected_rows: 1
89+
env:
90+
STACKQL_GITHUB_USERNAME: ${{ secrets.STACKQL_GITHUB_USERNAME }}
91+
STACKQL_GITHUB_PASSWORD: ${{ secrets.STACKQL_GITHUB_PASSWORD }}
92+
TEST_ORG: ${{ vars.TEST_ORG }}
93+
TEST_REPO: ${{ vars.TEST_REPO }}
94+
```
95+
96+
3697

37-
## Input
38-
- `auth_obj_path` - Path to the auth object file.
39-
- `auth_str` - Auth string.
40-
- `test_query` - Test query to run (overrides test_query_path).
41-
- `test_query_file_path` - Path to the test query file.
42-
- `expected_rows` - Expected number of rows in the result.
43-
- `expected_results_str` - expected result from executing test query, support object string (overrides expected_results_file_path)
44-
- `expected_results_file_path` - file that stores expected result, json is support

action.yml

+19-11
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,32 @@ name: 'StackQL Studios - StackQL Assert'
22
description: 'run StackQL query to test and audit your infrastructure.'
33
author: 'Yuncheng Yang, StackQL Studios'
44
inputs:
5-
auth_obj_path:
6-
description: file path to json object of stackql auth
7-
required: false
8-
auth_str:
9-
description: json string of stackql auth
10-
required: false
115
test_query:
12-
description: stackql query to be executed
6+
description: stackql query to execute (need to supply either test_query or test_query_file_path)
137
required: false
148
test_query_file_path:
15-
description: stackql query file to be executed
9+
description: stackql query file to execute (need to supply either test_query or test_query_file_path)
10+
required: false
11+
data_file_path:
12+
description: path to data file to pass to the stackql query preprocessor (json or jsonnet file)
13+
required: false
14+
vars:
15+
description: 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
1616
required: false
1717
expected_rows:
1818
description: expected number of rows from executing test query
1919
required: false
2020
expected_results_str:
21-
description: expected result from executing test query, support json string, overrides expected_results_file_path
21+
description: expected result (as a json string) from executing test query, overrides expected_results_file_path
2222
required: false
2323
expected_results_file_path:
24-
description: file that stores expected result, json is support
24+
description: json file with the expected result
25+
required: false
26+
auth_obj_path:
27+
description: the path of json file that stores stackql AUTH string (only required when using non-standard environment variable names)
28+
required: false
29+
auth_str:
30+
description: stackql AUTH string (only required when using non-standard environment variable names)
2531
required: false
2632

2733
runs:
@@ -39,7 +45,7 @@ runs:
3945
4046
4147
- name: Setup StackQL
42-
uses: stackql/setup-stackql@v1.1.0
48+
uses: stackql/setup-stackql@v1.2.0
4349
if: ${{steps.check-stackql.outputs.stackql_installed == 'false'}}
4450
with:
4551
use_wrapper: true
@@ -68,6 +74,8 @@ runs:
6874
env:
6975
QUERY_FILE_PATH: ${{ inputs.test_query_file_path }}
7076
QUERY: ${{inputs.test_query}}
77+
DATA_FILE_PATH: ${{inputs.data_file_path}}
78+
VARS: ${{inputs.vars}}
7179
OUTPUT: 'json'
7280

7381
- name: execute stackql command

lib/assert.js

+21-11
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,32 @@ const checkResult = (expectedResult, expectedRows, actualResult) => {
3939
// if both passed, check both
4040
if (expectedRows) {
4141
equality = actualResult.length === expectedRows;
42-
message = `============ StackQL Assert Failed ============ \n
43-
Expected Number of Rows: ${expectedRows} \n
44-
Actual Number of Rows: ${actualResult.length}
45-
Execution Result: ${JSON.stringify(actualResult)}
46-
`;
42+
if(equality) {
43+
message = `============ StackQL Assert Successful (row count) ============ \n
44+
Expected Number of Rows: ${expectedRows} \n
45+
Actual Number of Rows: ${actualResult.length} \n
46+
`;
47+
} else {
48+
message = `============ StackQL Assert Failed (row count) ============ \n
49+
Expected Number of Rows: ${expectedRows} \n
50+
Actual Number of Rows: ${actualResult.length} \n
51+
Execution Result: ${JSON.stringify(actualResult)} \n
52+
`;
53+
}
4754
}
4855

4956
if (expectedResult) {
5057
equality = JSON.stringify(expectedResult) === JSON.stringify(actualResult);
51-
message = `============ StackQL Assert Failed ============ \n
52-
Expected: ${JSON.stringify(expectedResult)}\n
53-
Actual: ${JSON.stringify(actualResult)}
54-
`;
58+
if(equality) {
59+
message = `============ StackQL Assert Successful (expected results) ============`;
60+
} else {
61+
message = `============ StackQL Assert Failed (expected results) ============ \n
62+
Expected: ${JSON.stringify(expectedResult)}\n
63+
Actual: ${JSON.stringify(actualResult)}
64+
`;
65+
}
5566
}
5667

57-
5868
return { equality, message };
5969
};
6070

@@ -106,7 +116,7 @@ const assertResult = (coreObj) =>{
106116

107117
const {equality, message} = checkResult(expectedResult, expectedRows, actualResult);
108118
if (equality) {
109-
core.info("============ StackQL Assert Succeed ============ ");
119+
core.info(message);
110120
} else {
111121
core.setFailed(message);
112122
}

0 commit comments

Comments
 (0)