Skip to content

feat: add reusable CI validation utilities for development automation - #182

Merged
d-ulker merged 1 commit into
mainfrom
feat/extract-ci-validation-utils
Sep 25, 2025
Merged

feat: add reusable CI validation utilities for development automation#182
d-ulker merged 1 commit into
mainfrom
feat/extract-ci-validation-utils

Conversation

@d-ulker

@d-ulker d-ulker commented Sep 25, 2025

Copy link
Copy Markdown
Owner

Summary

Strategic extraction from monster PR #171 as part of Phase 3A focused decomposition.

Adds reusable validation helpers that reduce boilerplate and provide clearer failure semantics in CI scripts:

  • 📊 Metric Range Validation: Ensures metrics stay within [0, 1] bounds with descriptive error messages
  • 🔑 Required Keys Validation: Validates object structure with human-readable error formatting
  • 🔍 Attribute Validation: Checks object attributes with specific AttributeError messaging
  • ✅ Declarative Assertions: ensure() helper for clean test condition validation
  • 🎯 Type-Safe Design: Specific exception types (ValueError, KeyError, AttributeError, AssertionError)

Key Features

  • Clear Error Messages: Human-readable field names (underscore → space conversion)
  • Type Safety: Proper numeric conversion with exception chaining
  • Reusable Design: Generic helpers that work across different CI contexts
  • Declarative Style: Keeps test bodies clean and focused on logic
  • Comprehensive Coverage: Handles metrics, structure, attributes, and conditions

Validation Types

# Metric validation (0-1 range)
validate_metric_ranges(metrics, ['accuracy', 'precision', 'recall'])

# Structure validation  
validate_required_keys(config, ['api_key', 'model_path'], 'configuration')

# Attribute validation
validate_hasattrs(model, ['predict', 'fit'], 'ML model')

# Declarative assertions
ensure(len(results) > 0, "Results should not be empty")

Test Plan

  • Unit tests for each validation function
  • Error message format validation
  • Integration tests with existing CI scripts
  • Edge case testing (empty inputs, invalid types)
  • Exception chaining verification

🏰 Fortress-Protected Development: Single-purpose micro-PR (1 file, CI utility enhancement)

🤖 Generated with Claude Code

Summary by Sourcery

Extract and refine reusable CI validation utilities for checking metric ranges, required keys, object attributes, and declarative assertions with precise exception types and clear error messages

New Features:

  • Add validate_metric_ranges to enforce that specified metrics are within the [0, 1] range
  • Add validate_required_keys to ensure required dictionary keys are present
  • Add validate_hasattrs to verify that an object has specified attributes
  • Add ensure for declarative assertions with custom error messages

Enhancements:

  • Standardize docstring formatting with structured exception sections
  • Reformat function signatures and spacing for improved readability

Documentation:

  • Update docstrings for clearer descriptions and structured Raises sections

Summary by CodeRabbit

  • New Features
    • Added robust validation for metric ranges (0.0–1.0), required keys, and required attributes, providing clear, actionable error messages.
  • Bug Fixes
    • Prevents invalid or missing metrics and misconfigured objects from slipping through by enforcing strict checks and raising informative errors.
  • Documentation
    • Improved and clarified function docstrings for easier understanding.
  • Style
    • Minor formatting updates for consistency; no behavior changes to existing utilities outside the new validations.

Extracted from monster PR #171 as part of Phase 3A strategic decomposition.

CI validation helpers providing:
- Metric range validation (0-1 bounds checking)
- Required keys validation with clear error messages
- Attribute existence validation for objects
- Declarative assertion helper for test conditions
- Type-safe validation with specific exception types

Reduces boilerplate in CI scripts and provides clearer failure semantics.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 25, 2025 14:05
@sourcery-ai

sourcery-ai Bot commented Sep 25, 2025

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Extract reusable validation helpers for CI scripts into a dedicated module, providing type-safe utilities with clear error messages and declarative assertions.

File-Level Changes

Change Details Files
Add reusable CI validation helpers for metrics, keys, attributes, and assertions
  • Introduce validate_metric_ranges to enforce [0,1] bounds with descriptive errors
  • Introduce validate_required_keys to ensure required keys with human-readable KeyError
  • Introduce validate_hasattrs to verify attribute presence with AttributeError
  • Add ensure helper for declarative assertion checks raising AssertionError
scripts/ci/validation_utils.py
Improve docstrings and code formatting for clarity
  • Standardize 'Raises' sections in docstrings using reStructuredText style
  • Convert function signatures to multi-line format for readability
  • Adjust docstring indentation and remove trailing blank lines
scripts/ci/validation_utils.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Sep 25, 2025

Copy link
Copy Markdown

Walkthrough

Implemented concrete validation logic in three functions within scripts/ci/validation_utils.py: validating metric ranges (0.0–1.0), ensuring required keys exist, and verifying required attributes on instances. Exceptions now include descriptive messages. Docstrings and formatting updated; no public API changes.

Changes

Cohort / File(s) Summary
Validation utilities
scripts/ci/validation_utils.py
Implemented validate_metric_ranges (numeric conversion, 0–1 checks, missing metrics), validate_required_keys (presence checks, KeyError), validate_hasattrs (attribute checks, AttributeError); updated docstrings/formatting; added trailing newline to ensure section; no API signature changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor CI as CI Script
  participant VU as validation_utils

  CI->>VU: validate_required_keys(obj, required)
  alt missing key
    VU-->>CI: raise KeyError("missing: ...")
  else all present
    VU-->>CI: return None
  end

  CI->>VU: validate_hasattrs(instance, attrs)
  alt missing attribute
    VU-->>CI: raise AttributeError("missing: ...")
  else all present
    VU-->>CI: return None
  end

  CI->>VU: validate_metric_ranges(metrics, required)
  alt missing metric
    VU-->>CI: raise ValueError("missing metric: ...")
  else non-numeric or out of [0.0,1.0]
    VU-->>CI: raise ValueError("invalid value: ...")
  else all valid
    VU-->>CI: return None
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I thump my paws in tidy glee,
Three checks now hop through CI’s lea—
Keys and attrs, metrics tight,
Bounds from dusk to dawn’s first light.
With whiskered wisdom, exceptions clear,
Our burrow’s builds hold nothing to fear. 🐇✅

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title clearly summarizes the primary change by indicating the addition of reusable CI validation utilities for development automation with a conventional “feat:” prefix. It matches the content and scope of the changeset without listing specific files or extraneous details. The phrasing is both clear and concise so that a reviewer scanning history can immediately understand the purpose of the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/extract-ci-validation-utils

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @uelkerd, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a dedicated module for reusable validation utilities, strategically extracted from a larger development effort. The primary goal is to enhance the robustness and maintainability of CI scripts by providing standardized functions for validating metric ranges, required dictionary keys, object attributes, and general conditions. These utilities are designed to reduce boilerplate code and offer more informative error feedback during automated checks, thereby streamlining the development automation process.

Highlights

  • Reusable CI Validation Utilities: Introduces a new Python module validation_utils.py to provide standardized and reusable validation functions for CI scripts, reducing boilerplate and improving failure semantics.
  • Metric Range Validation: Adds validate_metric_ranges to ensure that specified metrics fall within a defined numerical range (e.g., 0 to 1), raising a ValueError with a descriptive message if violated.
  • Required Keys Validation: Implements validate_required_keys to verify the presence of essential keys within a dictionary, raising a KeyError if any required key is missing.
  • Attribute Validation: Provides validate_hasattrs to confirm that an object possesses all necessary attributes, raising an AttributeError if an attribute is not found.
  • Declarative Assertions: Includes an ensure() helper function for clean, declarative condition validation, which raises an AssertionError with a custom message if the condition is false.
  • Improved Error Semantics: All validation functions utilize specific exception types (ValueError, KeyError, AttributeError, AssertionError) and generate human-readable error messages for clearer diagnostics.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@deepsource-io

deepsource-io Bot commented Sep 25, 2025

Copy link
Copy Markdown
Contributor

Here's the code health analysis summary for commits fc6e52a..2b70723. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource Test coverage LogoTest coverage⚠️ Artifact not reportedTimed out: Artifact was never reportedView Check ↗
DeepSource Python LogoPython✅ Success
🎯 3 occurences resolved
View Check ↗
DeepSource Terraform LogoTerraform✅ SuccessView Check ↗
DeepSource Secrets LogoSecrets✅ SuccessView Check ↗
DeepSource Shell LogoShell✅ SuccessView Check ↗
DeepSource Docker LogoDocker✅ SuccessView Check ↗

💡 If you’re a repository administrator, you can configure the quality gates from the settings.

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey there - I've reviewed your changes - here's some feedback:

  • Standardize the docstring style across all helpers (e.g. fully adopt NumPy or Google style) to keep parameter and raises sections consistent.
  • Consider using Mapping[str, Any] instead of dict[str, Any] for the metric and key validators to allow broader input types (e.g. custom dict subclasses).
  • The ensure() helper has a very generic name and could collide with other utilities—consider renaming it to something more descriptive (e.g. assert_condition or require) to avoid confusion.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Standardize the docstring style across all helpers (e.g. fully adopt NumPy or Google style) to keep parameter and raises sections consistent.
- Consider using Mapping[str, Any] instead of dict[str, Any] for the metric and key validators to allow broader input types (e.g. custom dict subclasses).
- The ensure() helper has a very generic name and could collide with other utilities—consider renaming it to something more descriptive (e.g. `assert_condition` or `require`) to avoid confusion.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copilot AI left a comment

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.

Pull Request Overview

Adds reusable validation utilities for CI automation to reduce boilerplate and provide clearer error semantics. The module introduces validation functions for metric ranges, required keys, object attributes, and general assertions with type-specific exceptions.

  • New validation utilities module with functions for metrics, keys, attributes, and conditions
  • Improved docstring formatting using numpydoc-style "Raises" sections
  • Type-safe design with specific exception types (ValueError, KeyError, AttributeError, AssertionError)

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +14 to +15
Raises
------

Copilot AI Sep 25, 2025

Copy link

Choose a reason for hiding this comment

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

The docstring format should use 'Raises:' with a colon instead of 'Raises' with dashes for consistency with Python docstring conventions.

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +39
Raises
------

Copilot AI Sep 25, 2025

Copy link

Choose a reason for hiding this comment

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

The docstring format should use 'Raises:' with a colon instead of 'Raises' with dashes for consistency with Python docstring conventions.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +56
Raises
------

Copilot AI Sep 25, 2025

Copy link

Choose a reason for hiding this comment

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

The docstring format should use 'Raises:' with a colon instead of 'Raises' with dashes for consistency with Python docstring conventions.

Copilot uses AI. Check for mistakes.

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request introduces a set of reusable validation utility functions for CI scripts, with changes focused on improving code style through consistent docstring formatting and standardized function signatures. The stylistic changes are well-executed and improve readability. My feedback focuses on further enhancing the utility of these functions. I've suggested improvements for validate_required_keys and validate_hasattrs to provide more comprehensive error messages by reporting all missing items at once, rather than failing on the first one. This change would significantly improve the debugging experience, aligning with the PR's goal of providing 'clearer failure semantics'.

Comment on lines +31 to +35
def validate_required_keys(
obj: dict[str, Any],
keys: Iterable[str],
label: str = "object",
) -> None:

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.

medium

The current implementation iterates through keys and fails on the first one that's missing. For a better developer experience, consider collecting all missing keys and reporting them in a single KeyError. This would allow a developer to fix all missing keys at once. You could achieve this efficiently using set operations to find the difference between the required keys and the keys present in the object.

Comment on lines +48 to +52
def validate_hasattrs(
instance: Any,
attrs: Iterable[str],
label: str = "object",
) -> None:

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.

medium

Similar to validate_required_keys, this function fails on the first missing attribute. It would be more helpful to report all missing attributes in a single AttributeError. You could do this by iterating through all attributes, collecting the missing ones in a list, and then raising an exception with a consolidated error message if the list is not empty.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
scripts/ci/validation_utils.py (2)

18-28: Humanize missing-metric errors for consistency

Right now the out-of-range path prettifies the metric name, but the missing-metric path reports the raw key. Hoisting the prettified name keeps both error paths uniform and a bit friendlier.

     for field in fields:
+        pretty = field.replace("_", " ").capitalize()
         if field not in metrics:
-            raise ValueError(f"Missing metric: {field}")
+            raise ValueError(f"{pretty} metric is missing")
         value = metrics[field]
         try:
             numeric = float(value)
         except (TypeError, ValueError) as exc:  # non-numeric
             raise ValueError(f"Metric '{field}' is not numeric: {value}") from exc
         if not 0.0 <= numeric <= 1.0:
-            pretty = field.replace("_", " ").capitalize()
             raise ValueError(f"{pretty} should be between 0 and 1")

31-45: Broaden the key container to Mapping

We only rely on __contains__, so widening the annotation lets callers pass read-only mappings or other dict-like views without type ignore noise.

-from typing import Any, Iterable
+from typing import Any, Iterable, Mapping
@@
-def validate_required_keys(
-    obj: dict[str, Any],
+def validate_required_keys(
+    obj: Mapping[str, Any],
     keys: Iterable[str],
     label: str = "object",
 ) -> None:
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc6e52a and 2b70723.

📒 Files selected for processing (1)
  • scripts/ci/validation_utils.py (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Sourcery review
  • GitHub Check: Analyze (python)
🔇 Additional comments (2)
scripts/ci/validation_utils.py (2)

2-5: Docstring context reads well

The expanded module docstring concisely explains the intent behind these helpers and sets the right expectations for callers.


59-61: Attribute validation message is precise

Good job surfacing both the label and exact attribute name; the resulting AttributeError reads clearly for CI logs.

@d-ulker
d-ulker merged commit 69644db into main Sep 25, 2025
12 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants