Skip to content

ci: enforce interrogate docstring coverage and restructure CI - #65

Merged
IceCodeNew merged 4 commits into
masterfrom
feat/interrogate-docstring-coverage
Jul 17, 2026
Merged

ci: enforce interrogate docstring coverage and restructure CI#65
IceCodeNew merged 4 commits into
masterfrom
feat/interrogate-docstring-coverage

Conversation

@IceCodeNew

@IceCodeNew IceCodeNew commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

Introduce interrogate for docstring coverage, sync its scope with the existing ruff D rules, and restructure the CI/Lint/Unittest workflows into clear, non-overlapping roles.

Changes

ci: merge lint workflow into CI

  • Move the Dockerfile hadolint step into ci.yml as its own job with job-scoped permissions: { pull-requests: read, checks: write }; the workflow keeps permissions: {}.
  • Extend CI triggers to master pushes and Dockerfile / .dockerignore changes.
  • Delete lint.yml. Its ruff-action steps are redundant with uv run ruff check and the prek ruff hooks.

ci: confine pytest to unittest workflow

  • Remove pytest and the Python version matrix from ci.yml — unit tests + coverage are unittest.ymls job.
  • Run the remaining CI checks on the latest Python (python-version: "3.x" + check-latest: true) and rename the job testlint.

feat(ci): enforce docstring coverage with interrogate

  • Add interrogate>=1.7,<2 dev dependency + [tool.interrogate] configured to mirror ruff D: style = "google", ignore semiprivate/private/nested functions, fail-under = 100, exclude tests/tooling dirs.
  • Wire the check into prek (pass_filenames = false, explicit weather_briefing path) and the CI lint job (uv run interrogate weather_briefing).

Verification

The interrogate config is verified to match ruff --select D exactly: both report 100% coverage of weather_briefing (ruff D does not check private/semiprivate/nested functions or tests/**, and the interrogate flags mirror that).

Local checks all green:

  • uv lock --check / uv sync --frozen
  • uv run ruff check → all checks passed
  • uv run interrogate weather_briefing → PASSED (100.0%, minimum 100.0)
  • prek run --all-files → all 16 hooks pass (incl. actionlint, TOML/YAML validation)
  • uv run pytest → 664 passed

Notes

  • No interrogate README badge (per decision).
  • Workflow role split: unittest.yml = unit tests + coverage (matrix 3.11–3.14 × ubuntu/macOS); ci.yml = lint/format/lock/prek/interrogate/gitleaks + hadolint.

Summary by CodeRabbit

  • Chores
    • Consolidated automated code-quality checks into the main CI workflow.
    • Added validation for Dockerfile changes.
    • Added documentation coverage checks requiring complete docstrings.
    • Updated development tooling configuration to support the new checks.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@IceCodeNew, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9966f775-172c-4792-b46d-65bdb5100702

📥 Commits

Reviewing files that changed from the base of the PR and between 2013367 and c287a0f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/lint.yml
  • .github/workflows/scan-all-commits.yml
  • prek.toml
  • pyproject.toml
📝 Walkthrough

Walkthrough

The changes consolidate linting into the CI workflow, add interrogate configuration and prek integration, trigger checks for container-file changes, and add Dockerfile validation through hadolint. The separate lint workflow is removed.

Changes

CI linting consolidation

Layer / File(s) Summary
Interrogate tooling configuration
pyproject.toml, prek.toml
Adds interrogate as a development dependency, configures strict Google-style docstring coverage, and registers its prek hook.
CI lint and Dockerfile jobs
.github/workflows/ci.yml, .github/workflows/lint.yml
Replaces the prior CI job section with linting, interrogate, gitleaks, and hadolint jobs; container-file changes now trigger CI, and the separate lint workflow is removed.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: enforcing interrogate docstring coverage and restructuring the CI workflows.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/interrogate-docstring-coverage

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.

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.74%. Comparing base (23ff5aa) to head (c287a0f).
⚠️ Report is 2 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master      #65   +/-   ##
=======================================
  Coverage   99.74%   99.74%           
=======================================
  Files          39       39           
  Lines        7144     7144           
  Branches      411      411           
=======================================
  Hits         7126     7126           
  Misses         13       13           
  Partials        5        5           

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

@IceCodeNew
IceCodeNew marked this pull request as ready for review July 17, 2026 12:21
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

CI: enforce interrogate docstring coverage and streamline workflows

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Consolidate lint/security checks in ci.yml (ruff, interrogate, gitleaks) on latest Python.
• Enforce 100% docstring coverage via interrogate, aligned to Ruff D scope.
• Move Dockerfile hadolint into CI as a dedicated job; delete redundant lint.yml.
Diagram

graph TD
  E["Push/PR"] --> CI["CI workflow (ci.yml)"] --> LINT["lint job"] --> RUFF["ruff check"]
  LINT --> INT["interrogate (coverage)"]
  CI --> HADO["hadolint job"]
  E --> UT["Unittest workflow"] --> PY["pytest matrix"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Ratcheted docstring coverage (baseline + incremental increase)
  • ➕ Avoids blocking merges if legacy modules are below 100%
  • ➕ Allows gradual adoption while still enforcing progress
  • ➖ More moving parts (baseline storage/updates)
  • ➖ Harder to reason about than a hard 100% gate
2. Rely on Ruff `D` rules only (no interrogate)
  • ➕ Single tool and consistent enforcement mechanism
  • ➕ No extra dependency/hook maintenance
  • ➖ Does not provide a coverage percentage gate
  • ➖ Can miss the policy goal of “everything public is documented”
3. Enforce docstrings via pydoclint/pydocstyle stricter rules (instead of coverage)
  • ➕ Richer structural/docstring-content validation than coverage alone
  • ➖ Different scope than Ruff D and can increase churn
  • ➖ Still not a direct coverage metric unless combined with another tool

Recommendation: The chosen approach (interrogate with config explicitly aligned to Ruff D, enforced in both CI and prek) is the most direct way to add a measurable docstring-coverage gate without changing existing lint semantics. If the codebase later grows and maintaining 100% becomes burdensome, consider a ratcheting approach, but for a greenfield/high-discipline repo the hard 100% threshold is appropriate.

Files changed (3) +37 / -7

Enhancement (1) +7 / -0
prek.tomlAdd interrogate hook pinned to 1.7.0 for docstring coverage +7/-0

Add interrogate hook pinned to 1.7.0 for docstring coverage

• Adds an interrogate repo entry and hook configured to run against the 'weather_briefing' package. Disables filename passing to ensure interrogate evaluates the intended module scope consistently.

prek.toml

Other (2) +30 / -7
ci.ymlRestructure CI into lint + hadolint jobs and add interrogate check +21/-7

Restructure CI into lint + hadolint jobs and add interrogate check

• Renames the main job to 'lint', removes the Python version matrix in favor of latest '3.x', and drops pytest from this workflow. Adds an 'interrogate' step for docstring coverage and introduces a dedicated 'hadolint' job with job-scoped permissions, while expanding PR path triggers to include Dockerfile changes.

.github/workflows/ci.yml

pyproject.tomlAdd interrogate dev dependency and align tool config with Ruff D rules +9/-0

Add interrogate dev dependency and align tool config with Ruff D rules

• Adds 'interrogate>=1.7,<2' to the dev dependency group and configures '[tool.interrogate]' for Google style with exclusions/ignores mirroring Ruff's docstring enforcement scope. Sets 'fail-under = 100' to enforce full docstring coverage.

pyproject.toml

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 31 rules

Grey Divider


Action required

1. interrogate rationale undocumented 📘 Rule violation ⚙ Maintainability
Description
A new third-party dev dependency interrogate was added without a documented rationale explaining
its purpose and where it is used. This violates the dependency-rationale requirement and makes
auditing/maintenance of dependency choices harder.
Code

pyproject.toml[31]

+  "interrogate>=1.7,<2",
Relevance

⭐⭐ Medium

No historical evidence found for “document new dependency rationale” enforcement; docs feedback
exists but not dependency-specific.

PR-#54
PR-#63
PR-#62

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The checklist requires documenting rationale for each new third-party dependency. interrogate is
newly added to the dev dependency group in pyproject.toml, and the existing dependency-notes
section does not include any rationale entry for it.

Rule 2141694: Document rationale for each new third-party dependency
pyproject.toml[28-35]
docs/notes.md[139-142]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new third-party dependency `interrogate` was added, but the repo does not document why it is needed and what feature/module uses it.

## Issue Context
Compliance requires each new dependency to have a documented rationale (purpose + where used). `interrogate` is introduced as a dev dependency and is wired into CI/prek, but there is no rationale recorded alongside the dependency declaration or in a canonical dependency rationale document.

## Fix Focus Areas
- pyproject.toml[28-35]
- docs/notes.md[139-142]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. CI checks bypassed by paths 🐞 Bug ⛨ Security
Description
The CI workflow is now the only place running ruff/interrogate/gitleaks, but it only triggers for
pull requests whose changed files match a small allowlist, so PRs changing other files can skip
linting, docstring coverage, and secret scanning entirely.
Code

.github/workflows/ci.yml[R10-17]

      - ".github/workflows/ci.yml"
      - "tests/**"
      - "weather_briefing/**"
+      - "Dockerfile"
+      - ".dockerignore"
      - "prek.toml"
      - "pyproject.toml"
      - "uv.lock"
Relevance

⭐⭐ Medium

No direct prior evidence on CI path allowlists; team does address CI safety/docs issues in workflow
PRs.

PR-#54
PR-#63
PR-#8

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
ci.yml limits execution to a path allowlist on pull_request, yet the same workflow is where
ruff/interrogate and gitleaks are run; other workflows shown (unittest/image/release) do not include
gitleaks or equivalent secret scanning, so skipping ci.yml skips these checks.

.github/workflows/ci.yml[4-18]
.github/workflows/ci.yml[23-46]
.github/workflows/unittest.yml[1-51]
.github/workflows/image.yml[1-16]
.github/workflows/release.yml[1-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`.github/workflows/ci.yml` only runs on pull requests that touch a limited set of paths. Since this workflow contains the repo’s `ruff`, `interrogate`, `prek`, and `gitleaks` steps, any PR that doesn’t touch one of the allowlisted paths will bypass these checks.

## Issue Context
This regression matters more now because `lint.yml` was deleted; checks that used to run on all PRs are now gated by `ci.yml`’s allowlist.

## Fix Focus Areas
- .github/workflows/ci.yml[4-18]

### Suggested fix options
- Remove `on.pull_request.paths` from `ci.yml` so the workflow runs on all PRs.
- Or switch to `paths-ignore` to only skip truly irrelevant files.
- Or split security-critical scanning (e.g., gitleaks) into a separate workflow that runs on all PRs/pushes regardless of changed paths.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. No lint on master push 🐞 Bug ☼ Reliability
Description
After removing the dedicated lint workflow, the remaining CI workflow only runs on pushes to
renovate/** (not master), so ruff/interrogate/prek/gitleaks won’t run on main-branch push events
(including post-merge pushes).
Code

.github/workflows/lint.yml[L6-11]

-on:
-    push:
-      branches:
-        - "master"
-        - "renovate/**"
-    pull_request:
Relevance

⭐⭐⭐ High

Team invests in ensuring CI runs on master pushes (workflows consistently triggered on master in
prior CI/release PRs).

PR-#8
PR-#54
PR-#62

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
ci.yml is configured to run lint/docstring/gitleaks steps, but its push trigger excludes master,
so those steps won’t execute on master push events.

.github/workflows/ci.yml[4-8]
.github/workflows/ci.yml[23-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The repo’s lint/security checks are in `.github/workflows/ci.yml`, but that workflow does not trigger on pushes to `master`. With `lint.yml` deleted, there’s no longer a push-to-master validation for ruff/interrogate/prek/gitleaks.

## Issue Context
This impacts direct pushes and the push event that occurs when PRs are merged into `master`.

## Fix Focus Areas
- .github/workflows/ci.yml[4-8]

### Suggested fix
Add `master` to `on.push.branches` in `ci.yml` (and optionally keep `renovate/**`). If you intentionally only want PR-time validation, document that decision and consider keeping a lightweight post-merge workflow for at least gitleaks/ruff to protect the main branch.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread pyproject.toml
dev = [
"any-llm-sdk[all]>=1.19,<2",
"anyio>=4.11,<5",
"interrogate>=1.7,<2",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. interrogate rationale undocumented 📘 Rule violation ⚙ Maintainability

A new third-party dev dependency interrogate was added without a documented rationale explaining
its purpose and where it is used. This violates the dependency-rationale requirement and makes
auditing/maintenance of dependency choices harder.
Agent Prompt
## Issue description
A new third-party dependency `interrogate` was added, but the repo does not document why it is needed and what feature/module uses it.

## Issue Context
Compliance requires each new dependency to have a documented rationale (purpose + where used). `interrogate` is introduced as a dev dependency and is wired into CI/prek, but there is no rationale recorded alongside the dependency declaration or in a canonical dependency rationale document.

## Fix Focus Areas
- pyproject.toml[28-35]
- docs/notes.md[139-142]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread .github/workflows/ci.yml
Comment on lines 10 to 17
- ".github/workflows/ci.yml"
- "tests/**"
- "weather_briefing/**"
- "Dockerfile"
- ".dockerignore"
- "prek.toml"
- "pyproject.toml"
- "uv.lock"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Ci checks bypassed by paths 🐞 Bug ⛨ Security

The CI workflow is now the only place running ruff/interrogate/gitleaks, but it only triggers for
pull requests whose changed files match a small allowlist, so PRs changing other files can skip
linting, docstring coverage, and secret scanning entirely.
Agent Prompt
## Issue description
`.github/workflows/ci.yml` only runs on pull requests that touch a limited set of paths. Since this workflow contains the repo’s `ruff`, `interrogate`, `prek`, and `gitleaks` steps, any PR that doesn’t touch one of the allowlisted paths will bypass these checks.

## Issue Context
This regression matters more now because `lint.yml` was deleted; checks that used to run on all PRs are now gated by `ci.yml`’s allowlist.

## Fix Focus Areas
- .github/workflows/ci.yml[4-18]

### Suggested fix options
- Remove `on.pull_request.paths` from `ci.yml` so the workflow runs on all PRs.
- Or switch to `paths-ignore` to only skip truly irrelevant files.
- Or split security-critical scanning (e.g., gitleaks) into a separate workflow that runs on all PRs/pushes regardless of changed paths.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

pull-requests: read
checks: write

on:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. No lint on master push 🐞 Bug ☼ Reliability

After removing the dedicated lint workflow, the remaining CI workflow only runs on pushes to
renovate/** (not master), so ruff/interrogate/prek/gitleaks won’t run on main-branch push events
(including post-merge pushes).
Agent Prompt
## Issue description
The repo’s lint/security checks are in `.github/workflows/ci.yml`, but that workflow does not trigger on pushes to `master`. With `lint.yml` deleted, there’s no longer a push-to-master validation for ruff/interrogate/prek/gitleaks.

## Issue Context
This impacts direct pushes and the push event that occurs when PRs are merged into `master`.

## Fix Focus Areas
- .github/workflows/ci.yml[4-8]

### Suggested fix
Add `master` to `on.push.branches` in `ci.yml` (and optionally keep `renovate/**`). If you intentionally only want PR-time validation, document that decision and consider keeping a lightweight post-merge workflow for at least gitleaks/ruff to protect the main branch.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Move the Dockerfile hadolint step into the CI workflow with job-scoped
permissions (pull-requests: read, checks: write) so the workflow keeps
minimal grants. Extend the CI triggers to master pushes and Dockerfile
and .dockerignore changes. Drop lint.yml; its ruff-action steps are
redundant with the existing uv-run ruff check and the prek ruff hooks.
Drop pytest and the Python version matrix from the CI workflow; unit
tests and coverage are the unittest workflow's responsibility. Run the
remaining checks (lock, prek, ruff, gitleaks) on the latest Python 3.x
and rename the job to lint to reflect its purpose.
Add interrogate 1.7 as a development dependency and configure it under
[tool.interrogate] to mirror the ruff D rules: google style, ignore
semiprivate, private, and nested functions, fail-under 100, and exclude
tests and tooling directories. The config is verified to match ruff's
--select D scope (both report full coverage of weather_briefing).

Wire the check into both the prek hook suite (pass_filenames=false,
explicit weather_briefing path) and the CI lint job. The hook env pins
interrogate at the 1.7.0 tag while the dev dependency lets the explicit
CI step and local uv run share the same configuration.
@IceCodeNew
IceCodeNew force-pushed the feat/interrogate-docstring-coverage branch from 2013367 to c287a0f Compare July 17, 2026 12:39
@IceCodeNew
IceCodeNew merged commit 5d2154e into master Jul 17, 2026
15 checks passed
@IceCodeNew
IceCodeNew deleted the feat/interrogate-docstring-coverage branch July 17, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant