Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema adherence validator #77

Merged
merged 6 commits into from
Sep 11, 2023
Merged

Schema adherence validator #77

merged 6 commits into from
Sep 11, 2023

Conversation

l50
Copy link
Contributor

@l50 l50 commented Sep 7, 2023

Proposed Changes

  • Created YAML schema for TTPs (docs/ttpforge-spec.yaml)
  • Streamlined the YAML validation process, introducing enhanced clarity and comprehensive error messaging.
  • Consolidated YAML validation into a shared function and introduced a pre-commit hook mechanism to preemptively prevent committing non-conforming YAML files.
  • Updated .pre-commit-config.yaml to include the new validate-yaml-files hook and added a schema file ttpforge-spec.yaml for TTP YAML files structure and properties definition.
  • Enhanced magefile functions for more robust validation and improved handling of various scenarios.

Related Issue(s)

N/A

Testing

  • Introduced a pre-commit hook script validate-yaml.sh to validate all committed YAML files against a predefined schema.
  • Added and improved functions in magefile.go, such as ValidateYAML, which leverages the newly defined schema for validation.
  • Dependencies were updated and tested for compatibility.
  • Detailed testing information can be found here: Schema adherence validator #77 (comment)

Documentation

  • Updated the documentation to include a new schema file ttpforge-spec.yaml under the docs/ directory.
  • The new validate-yaml-files hook was documented in .pre-commit-config.yaml.
  • Additional documentation regarding enhanced validation and error messaging was integrated into relevant function definitions and usage scenarios.

Screenshots/GIFs (optional)

N/A

Checklist

  • Ran mage runprecommit locally and fixed any issues that arose.
  • Curated your commit(s) so they are legible and easy to read and understand.
  • 🚀

@TTPForge-bot TTPForge-bot added area/pre-commit Changes made to pre-commit hooks area/mage labels Sep 7, 2023
@l50 l50 changed the title Validate yaml Schema adherence validator Sep 7, 2023
@l50 l50 enabled auto-merge (squash) September 7, 2023 23:01
@l50 l50 disabled auto-merge September 7, 2023 23:02
@l50 l50 enabled auto-merge (squash) September 7, 2023 23:04
@l50 l50 requested a review from cedowens September 7, 2023 23:07
@l50
Copy link
Contributor Author

l50 commented Sep 7, 2023

This PR is a blocking pre-requisite for facebookincubator/TTPForge#83

@d3sch41n
Copy link
Contributor

d3sch41n commented Sep 8, 2023

Hey there, could you please post a couple (3-ish) screenshots of what different kinds of YAML validation failures look like to the end user who runs pre-commit.

This will help determine whether this should be a user-facing feature baked into pre-commit or something used ad-hoc for ART imports.

@l50
Copy link
Contributor Author

l50 commented Sep 8, 2023

Hey there, could you please post a couple (3-ish) screenshots of what different kinds of YAML validation failures look like to the end user who runs pre-commit.

This will help determine whether this should be a user-facing feature baked into pre-commit or something used ad-hoc for ART imports.

Absolutely! Here's an example of how we can get this to flag an invalid TTP:

cp ttps/examples/sub-ttps/example.yaml ttps/examples/sub-ttps/broken-example.yaml

Next, we make the following changes to broken-example.yaml:

diff ttps/examples/sub-ttps/example.yaml ttps/examples/sub-ttps/broken-example.yaml
5,6c5
<   - name: first_sub_ttp
<     ttp: examples/sub-ttps/my-sub-ttps/ttp1.yaml
---
>   - ttp: examples/sub-ttps/my-sub-ttps/ttp1.yaml

As you can see, the step no longer has a name, which is not going to work.

Next, we add the commit:

git add ttps/examples/sub-ttps/broken-example.yaml

When we run git commit, the following feedback will be provided by pre-commit:

...
Validate all committed YAML files against TTPForge schema.........................Failed
- hook id: validate-yaml-files
- exit code: 1

Files to validate: ttps/examples/sub-ttps/broken-example.yaml
Error: the "name" property is missing when "ttp" is defined in a step
Failed validation for: ttps/examples/sub-ttps/broken-example.yaml

Here's another example:

cp ttps/examples/steps/edit-step/ttp.yaml ttps/examples/steps/edit-step/broken-ttp.yaml 

Next, we make the following changes to broken-ttp.yaml:

diff ttps/examples/steps/edit-step/ttp.yaml ttps/examples/steps/edit-step/broken-ttp.yaml
9,10c9
<       - old: REPLACE_ME
<         new: REPLACED_BY_EDIT
---
>       - new: REPLACED_BY_EDIT

As you can see, the step no longer has an old step, which is not going to work.

Next, we add the commit:

git add ttps/examples/steps/edit-step/broken-ttp.yaml

When we run git commit, the following feedback will be provided:

Validate all committed YAML files against TTPForge schema.........................Failed
- hook id: validate-yaml-files
- exit code: 1

Files to validate: ttps/examples/steps/edit-step/broken-ttp.yaml
Error: an edit item is missing the 'old' field
Failed validation for: ttps/examples/steps/edit-step/broken-ttp.yaml

For the third example:

cp ttps/examples/args/define-args.yaml ttps/examples/args/broken-args.yaml

Next, we make the following changes to broken-args.yaml:

diff ttps/examples/args/define-args.yaml ttps/examples/args/broken-args.yaml
7,8c7
<   - name: a_number
<     type: int
---
>   - type: int

As you can see, the step no longer has a name, which is not going to work.

Next, we add the commit:

git add ttps/examples/args/broken-args.yaml

When we run git commit, the following feedback will be provided:

Validate all committed YAML files against TTPForge schema.........................Failed
- hook id: validate-yaml-files
- exit code: 1

Files to validate: ttps/examples/args/broken-args.yaml
Error: an argument item is missing the 'name' field
Failed validation for: ttps/examples/args/broken-args.yaml

l50 added 6 commits September 8, 2023 17:29
- Introduced a new pre-commit hook script `validate-yaml.sh` to validate all committed YAML files against a predefined schema using mage's `validateallyamlfiles` command.
- Updated `.pre-commit-config.yaml` to include the new `validate-yaml-files` hook.
- Added a new schema file `ttpforge-spec.yaml` under the `docs/` directory to define the structure and properties for the TTP YAML files.
- Enhanced the `magefile.go` to include the new function `ValidateAllYAMLFiles` which uses the schema for validation.
- Dependencies were updated in `magefiles/go.mod` and `magefiles/go.sum`.
- Streamlined the YAML validation process by consolidating it into a shared function.
- Improved error messaging for enhanced clarity.
- Established a new function, loadSchema, to facilitate schema loading and unmarshalling from a YAML file.
- Enhanced ValidateYAML to accommodate schema path input and extended support for directory-wide YAML file validation.
- Revised the validateAllYAML function to furnish comprehensive error messages and enhanced logging.
- Elevated error handling for YAML validation by providing informative error messages.
- Augmented the inspectAndValidate function to adeptly manage nested SubTTPSteps and validate referenced files.
- Implemented custom validation to ascertain the presence of the "name" property when "ttp" is declared in a step.

This commit amplifies the effectiveness of YAML file validation, ensuring strict adherence to the schema.
Introduces a pre-commit hook mechanism to preemptively thwart the commitment of non-conforming YAML files.
- Fixed concurrency and infinite recursion bugs
- Resolved issue with having set -e set
- Optimized output to be useful
…alidator.go.

- Fixed failures to catch problems in editsteps and args
@d3sch41n
Copy link
Contributor

d3sch41n commented Sep 11, 2023

Thank you for the test cases. Seems like there are two possible approaches:

  1. Validate adherence within the existing Validate(...) functions of the TTP and steps
    • Pros - can add more complex validation conditions, since we can write them in golang
    • Cons - potentially more verbose because the YAML setup we are using doesn't make it easy to mark fields as required
  2. Use a schema as shown here
    • Pros - pretty good error messages out of the box
    • Cons - need to write everything twice, once in the YAML config for the structs within Go, and once here. More dev overhead

The existing code catches all of these test cases, but it is only called from run, so we'd need to add a skeleton validate command to TTPForge to use it in this context:

image image image

I'm cool with stamping this as an experiment that will tell us which approach is better, but I'm maxed out so @l50 you'll need to assume sole responsibility for keeping this schema up to date. Cool?

@l50
Copy link
Contributor Author

l50 commented Sep 11, 2023

I'm good with ownership of the schema to land it for now. I plan to automate its generation eventually - will just take some concerted effort on my part.

In the meantime, I've cut an FR to track it: #80

@d3sch41n
Copy link
Contributor

cool, ship

@d3sch41n d3sch41n closed this Sep 11, 2023
auto-merge was automatically disabled September 11, 2023 22:07

Pull request was closed

@d3sch41n d3sch41n reopened this Sep 11, 2023
Copy link
Contributor

@d3sch41n d3sch41n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fat fingered close - my bad, LGTM after discussion on schema ownership

@l50 l50 merged commit dbf997b into facebookincubator:main Sep 11, 2023
@l50 l50 deleted the validate-yaml branch September 11, 2023 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/mage area/pre-commit Changes made to pre-commit hooks cla signed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants