-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from helpfulengineering/gh-action
Initial github action logic
- Loading branch information
Showing
9 changed files
with
262 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
.git | ||
.devcontainer | ||
testschemas | ||
.vscode | ||
.devcontainer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
name: Python deploy | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
|
||
jobs: | ||
deploy: | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Bump version and push tag | ||
if: ${{ github.event_name == 'push' }} | ||
uses: anothrNick/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
WITH_V: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,51 @@ | ||
# ok-validate | ||
|
||
Validation of Open Know How specification and related schemas (https://openknowhow.org) | ||
## GitHub Action | ||
|
||
This action uses an Open Knowledge Framework schema to validate your manifest such as for [`OKH`](https://openknowhow.org/) | ||
|
||
### Inputs | ||
|
||
#### `cpu-num` | ||
|
||
*Optional* How many cores to use. Default `"4"`. | ||
|
||
#### `ok` | ||
|
||
*Optional* Which Open Knowledge Framework schema to use for validation. Default [`"okh"`](./okv/schemas/okh.yaml). | ||
|
||
#### `parser` | ||
|
||
*Optional* YAML library to load file. Default `"pyyaml"` (can be one of `"pyyaml"` or `"ruamel"`). | ||
|
||
#### `path` | ||
|
||
*Required* The path to your manifest or manifests relative to your workspace. Default `"./"`. | ||
|
||
#### `schema` | ||
|
||
*Optional* The full path to an Open Knowledge Framework schema or custom schema to use for validation. Default `""`. | ||
|
||
#### `strict` | ||
|
||
*Optional* Whether to run in strict mode. Default `"false"` (can be one of `"true"` or `"false"`). | ||
### Example usage | ||
|
||
```yaml | ||
uses: helpfulengineering/[email protected] | ||
``` | ||
```yaml | ||
uses: helpfulengineering/[email protected] | ||
with: | ||
path: './some/path/to/file.yaml' | ||
``` | ||
## Automatic releasing | ||
<https://github.com/anothrNick/github-tag-action#bumping> | ||
> Manual Bumping: Any commit message that includes #major, #minor, #patch, or #none will trigger the | ||
> respective version bump. If two or more are present, the highest-ranking one will take precedence. | ||
> If #none is contained in the commit message, it will skip bumping regardless DEFAUT_BUMP. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# action.yml | ||
name: 'ok-validate' | ||
description: 'Use an Open Knowledge Framework schema to validate your manifest' | ||
branding: | ||
icon: check-circle | ||
color: green | ||
inputs: | ||
cpu-num: | ||
description: 'How many cores to use' | ||
required: false | ||
default: '4' | ||
ok: | ||
description: 'Which preset Open Knowledge Framework schema to use for validation. Should be one of ("okh")' | ||
required: false | ||
default: 'okh' | ||
parser: | ||
description: 'YAML library to load file' | ||
required: false | ||
default: 'pyyaml' | ||
path: | ||
description: 'The path to your mainfest or manifests relative to your workspace' | ||
required: true | ||
default: './' | ||
schema: | ||
description: 'The full path to an Open Knowledge Framework schema or custom schema to use for validation' | ||
required: false | ||
default: '' | ||
strict: | ||
description: 'Should the schema validator be run in strict mode?' | ||
required: false | ||
default: 'false' | ||
outputs: | ||
results: | ||
description: 'The results of the validator' | ||
runs: | ||
using: 'docker' | ||
image: 'Dockerfile' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
set -ex | ||
|
||
if [ -z "${GITHUB_ACTIONS}" ]; then | ||
exec okv ${@} | ||
else | ||
strict_mode='--no-strict' | ||
if [ "${INPUT_STRICT}" = "true" ]; then strict_mode=''; fi | ||
INPUT_CPU_NUM="$(env | sed -n 's/^INPUT_CPU-NUM=\(.*\)/\1/p')" | ||
schema_flag="--ok=${INPUT_OK}" | ||
if [ ! -z "${INPUT_SCHEMA}" ]; then | ||
schema_flag="--schema=${INPUT_SCHEMA}" | ||
fi | ||
output=$(okv ${schema_flag} --cpu-num=${INPUT_CPU_NUM} --parser=${INPUT_PARSER} ${strict_mode} -path=${INPUT_PATH}) | ||
result=$? | ||
echo "::set-output name=results::$(echo $output)" | ||
if [ "${result}" != "0" ]; then exit 1; fi | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,136 @@ | ||
import argparse | ||
# Import Yamale and make a schema object: | ||
import datetime | ||
import os | ||
import sys | ||
|
||
import yamale | ||
import yaml | ||
from yamale.yamale_error import YamaleError | ||
import datetime | ||
|
||
from .validators import DefaultValidators, RootValidation | ||
import yaml | ||
import os | ||
|
||
|
||
|
||
def yamale_args_wrapper(): | ||
parser = argparse.ArgumentParser(description='Validate yaml files.') | ||
parser.add_argument('-path', metavar='PATH', default='./', nargs='?', | ||
help='folder to validate. Default is current directory.') | ||
parser.add_argument('-s', '--schema', | ||
help='filename of schema. Default is schema.yaml.') | ||
parser.add_argument('-n', '--cpu-num', default=4, type=int, | ||
help='number of CPUs to use. Default is 4.') | ||
parser.add_argument('-p', '--parser', default='pyyaml', | ||
help='YAML library to load files. Choices are "ruamel" or "pyyaml" (default).') | ||
parser.add_argument('--no-strict', action='store_true', | ||
help='Disable strict mode, unexpected elements in the data will be accepted.') | ||
parser.add_argument('--ok', default='okh', | ||
help='This indicates which Open Know specification to use.') | ||
parser.add_argument( | ||
'-path', | ||
metavar='PATH', | ||
default='./', | ||
nargs='?', | ||
help='folder to validate. Default is current directory.', | ||
) | ||
parser.add_argument( | ||
'-s', | ||
'--schema', | ||
help='filename of schema. Default is schema.yaml.', | ||
) | ||
parser.add_argument( | ||
'-n', '--cpu-num', | ||
default=4, | ||
type=int, | ||
help='number of CPUs to use. Default is 4.', | ||
) | ||
parser.add_argument( | ||
'-p', | ||
'--parser', | ||
default='pyyaml', | ||
help='YAML library to load files. Choices are "ruamel" or "pyyaml" (default).', | ||
) | ||
parser.add_argument( | ||
'--no-strict', | ||
action='store_true', | ||
help='Disable strict mode, unexpected elements in the data will be accepted.', | ||
) | ||
parser.add_argument( | ||
'--no-error', | ||
action='store_true', | ||
help='Ignore error when violation of schema is identified.', | ||
) | ||
parser.add_argument( | ||
'--ok', | ||
default='okh', | ||
help='This indicates which Open Know specification to use.' | ||
) | ||
return parser.parse_args() | ||
|
||
|
||
def included_ok_schema(oktype): | ||
module_root = os.path.abspath(os.path.dirname(__file__)) | ||
return os.path.join(module_root, 'schemas', oktype + '.yaml') | ||
return os.path.join(module_root, 'schemas', oktype.lower() + '.yaml') | ||
|
||
|
||
def composite_error_message(result, root_validation_error=None): | ||
results = [] | ||
for given_result in result: | ||
results.append(str(given_result)) | ||
if root_validation_error: | ||
for error_result in root_validation_error.results: | ||
for error in error_result.errors: | ||
error_string = '\t{0}'.format(str(error)) | ||
results.append(error_string) | ||
return '\n'.join(results) | ||
|
||
|
||
def _handle_error_exit(error_messages): | ||
raise_python_exception = False | ||
error_string = '\n----\n'.join(set(error_messages)) | ||
if raise_python_exception: | ||
raise ValueError(error_string) | ||
print(error_string) | ||
sys.exit(1) | ||
|
||
|
||
def main(): | ||
args = yamale_args_wrapper() | ||
validators = DefaultValidators.copy() | ||
schema_to_use = included_ok_schema(args.ok) if args.schema is None else args.schema | ||
results = [] | ||
data_filename_arr=[] | ||
string_error_messages = [] | ||
data_filename_arr = [] | ||
path_to_use = args.path | ||
strict = not args.no_strict | ||
raise_error = not args.no_error | ||
|
||
try: | ||
schema = yamale.make_schema(schema_to_use, validators=validators) | ||
if(path_to_use.endswith('.yaml') or path_to_use.endswith('.yml')): | ||
schema = yamale.make_schema(schema_to_use, validators=validators) | ||
path_to_use = os.path.abspath(path_to_use) | ||
if os.path.isfile(path_to_use): | ||
if (path_to_use.endswith('.yaml') or path_to_use.endswith('.yml')): | ||
data_filename_arr.append(path_to_use) | ||
else: | ||
for root, dirs, files in os.walk(path_to_use): | ||
for f in files: | ||
if (f.endswith('.yaml') or f.endswith('.yml')) and f != schema_to_use: | ||
data_filename_arr.append(args.path+"/"+f) | ||
|
||
file_count = 1 | ||
|
||
for d in data_filename_arr: | ||
# print(d) | ||
data = yamale.make_data(d) # currently single files | ||
# Create a Data object | ||
|
||
root_validation = RootValidation(schema=schema, data=data, validators=validators, args=args) | ||
pre_results = root_validation.validate() # single goes through here | ||
for p in pre_results: | ||
if '\'None\' is Valid' not in p: | ||
print(p) | ||
|
||
# root_level_validation(schema, data, validators, args) | ||
# Validate data against the schema. Throws a ValueError if data is invalid. | ||
mistake_made = False | ||
try: | ||
result = yamale.validate(schema, data, False, False) | ||
except (SyntaxError, NameError, TypeError, ValueError, YamaleError) as f: | ||
print(f) | ||
print(result) | ||
mistake_made = True | ||
|
||
if mistake_made == False: | ||
results_list = list(dict.fromkeys(result)) | ||
for r in results_list: | ||
print(r) | ||
|
||
if file_count < len(data_filename_arr): | ||
print("\n • • • \n") | ||
file_count += 1 | ||
|
||
except (SyntaxError, NameError, TypeError, ValueError, YamaleError) as e: | ||
err_type = str(type(e)).split("\'")[1]+": " | ||
print('Validation error!\n%s' % err_type+str(e)) | ||
print("Consider revising .yaml format.") | ||
else: | ||
for root, _dirs, files in os.walk(path_to_use): | ||
for file in files: | ||
if (file.endswith('.yaml') or file.endswith('.yml')) and file != schema_to_use: | ||
data_filename = os.path.join(root, file) | ||
data_filename_arr.append(data_filename) | ||
|
||
file_count = 1 | ||
|
||
for data_filename in data_filename_arr: | ||
data = yamale.make_data(data_filename) | ||
# Create a Data object | ||
root_validation = RootValidation(schema=schema, data=data, validators=validators, args=args) | ||
root_validation_error = None | ||
try: | ||
root_validation.validate() | ||
except (YamaleError) as err: | ||
root_validation_error = err | ||
|
||
# root_level_validation(schema, data, validators, args) | ||
# Validate data against the schema. Throws a ValueError if data is invalid. | ||
result = None | ||
should_raise_error = False if data_filename_arr else raise_error | ||
result = yamale.validate(schema, data, strict, should_raise_error) | ||
error_message = composite_error_message(result, root_validation_error) | ||
if error_message: | ||
string_error_messages.append(error_message) | ||
results.extend(result) | ||
|
||
if file_count < len(data_filename_arr): | ||
file_count += 1 | ||
|
||
if string_error_messages: | ||
_handle_error_exit(string_error_messages) | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.