Skip to content

feat(toolkit-lib): validate command#1508

Merged
kaizencc merged 13 commits into
mainfrom
conroyka/validate
May 20, 2026
Merged

feat(toolkit-lib): validate command#1508
kaizencc merged 13 commits into
mainfrom
conroyka/validate

Conversation

@kaizencc
Copy link
Copy Markdown
Contributor

@kaizencc kaizencc commented May 13, 2026

Summary

Adds a validate() method to the Toolkit class in @aws-cdk/toolkit-lib. This command:

  • Synthesizes the CDK app
  • Reads the policy-validation-report.json from the cloud assembly output directory (written by aws-cdk-lib during synthesis)
  • Returns a structured ValidateResult with overall pass/fail status and per-plugin reports

This is the toolkit-lib layer only — CLI wiring (cdk validate) will follow separately.

Changes

  • New action types (lib/actions/validate/index.ts): ValidateOptions, ValidateResult — uses schema types from @aws-cdk/cloud-assembly-schema (PR feat(cloud-assembly-schema): add policy validation report schema types #1515) rather than redefining them
  • New validate() method on the Toolkit class — reads the report JSON and casts to typed schema, no manual field mapping
  • IO messages: CDK_TOOLKIT_I9600 (passed), CDK_TOOLKIT_E9600 (failed), CDK_TOOLKIT_I9601 (no report found)
  • ToolkitAction: added validate to the union type

Dependencies

Test plan

  • Unit tests covering: success, failure, missing report, IO message emission, violation parsing, plugin version handling
  • Integration test with a CDK app that has validation plugins configured (blocked on aws-cdk-lib change)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 13, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.20%. Comparing base (791408c) to head (85e1659).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1508   +/-   ##
=======================================
  Coverage   88.20%   88.20%           
=======================================
  Files          76       76           
  Lines       10834    10834           
  Branches     1492     1492           
=======================================
  Hits         9556     9556           
  Misses       1250     1250           
  Partials       28       28           
Flag Coverage Δ
suite.unit 88.20% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment on lines +695 to +699
if (status === 'failure') {
await ioHelper.notify(IO.CDK_TOOLKIT_E9600.msg('Policy validation failed', result));
} else {
await ioHelper.notify(IO.CDK_TOOLKIT_I9600.msg('Policy validation passed', result));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we pick slightly less mechanical language here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"policy policy policy"

Let's speak like a human.

"cdk validate found problems" (or something to that effect), "no problems found", let's not pretend to be IBM and we all wear ties in triplicate.

@kaizencc kaizencc marked this pull request as ready for review May 18, 2026 15:39
const selectStacks = stacksOpt(options);
await using assembly = await synthAndMeasure(ioHelper, cx, selectStacks);

const reportPath = path.join(assembly.directory, POLICY_VALIDATION_REPORT_FILE);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should be an artifact in the manifest, no?

Although I can live with this for a bit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

status: 'success',
pluginReports: [],
};
await ioHelper.notify(IO.CDK_TOOLKIT_I9601.msg('No policy validation report found'));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is very mechanical. What does this mean to me as a user?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right now it means no plugins / no construct annotations / default rule set is turned off.

I could be convinced for this to not be possible and we always write a report no matter what

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

there's no default rule set right now so the message wont mention that for now


const reportJson = await fs.readJson(reportPath);

if (!Array.isArray(reportJson.pluginReports)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we do a JSON schema validation so we don't have to bother with this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

Comment on lines +695 to +699
if (status === 'failure') {
await ioHelper.notify(IO.CDK_TOOLKIT_E9600.msg('Policy validation failed', result));
} else {
await ioHelper.notify(IO.CDK_TOOLKIT_I9600.msg('Policy validation passed', result));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"policy policy policy"

Let's speak like a human.

"cdk validate found problems" (or something to that effect), "no problems found", let's not pretend to be IBM and we all wear ties in triplicate.

kaizencc and others added 13 commits May 20, 2026 13:35
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…lidate

Instead of redefining the policy validation report types locally,
import them from @aws-cdk/cloud-assembly-schema (added in PR #1515).
This removes ~130 lines of duplicate type definitions and simplifies
the validate method to a typed cast instead of manual field mapping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Handle malformed report: throw ToolkitError if pluginReports is
  missing or not an array
- Test constructStack (ConstructTraceJson): add recursive trace to
  fixture and assert nested id/construct/location fields
- Assert IO message data payload contains full ValidateResult
- Test missing title field gracefully results in undefined

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace 'as const' with explicit PolicyValidationReportStatus type annotation
- Extract 'policy-validation-report.json' to a file-level constant

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PolicyValidationReportStatus -> PolicyValidationReportConclusion
- PluginReportJson.summary.pluginName -> PluginReportJson.pluginName
- PluginReportJson.summary.status -> PluginReportJson.conclusion
- PluginReportJson.version -> PluginReportJson.pluginVersion
- PolicyViolationJson.fix -> PolicyViolationJson.suggestedFix
- ViolatingConstructJson restructured: resourceLogicalId/templatePath
  moved to cloudFormationResource, constructStack -> stackTraces
- ValidateResult.status -> ValidateResult.conclusion
- Update test fixtures and assertions to match
- Use friendlier message when no validation report exists: explain
  that no plugins are configured rather than stating a file is missing
- Remove manual pluginReports array check; trust the report format
  since it's written by aws-cdk-lib (not user-authored)
- "No validation plugins configured" instead of "No policy validation report found"
- "cdk validate found problems" instead of "Policy validation failed"
- "No problems found" instead of "All policy checks passed"
The policy-validation-report.json fixtures were missing the required
`version` field, causing Manifest.loadValidationReport to throw
"Invalid semver string: undefined" during schema validation.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants