feat: Implement autonomous repository management workflows and scripts - #176
feat: Implement autonomous repository management workflows and scripts#176NITISH-R-G wants to merge 4 commits into
Conversation
…lities - Setup community guidelines and templates - Configure AI PR reviewer action - Configure stale issues and greetings automations - Configure PR labeler based on file paths - Add codeql security analysis workflow - Add unified repo-maintenance workflow for formatting, linting, docs, kg, and sboms - Create ast-based automated docs syncing tool - Create ast-based automated knowledge graph generation tool - Setup dependabot for pip, npm, and gh-actions - Separate GitHub Pages deployment into its own workflow - Configure robust testing CI Co-authored-by: NITISH-R-G <225521762+NITISH-R-G@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Sorry @NITISH-R-G, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
Reviewer's GuideThis PR turns the repo into an autonomous, policy-governed project with nightly maintenance, security scanning, AI-assisted reviews, and auto-generated API docs/knowledge graph, primarily via new GitHub workflows and Python tooling that introspects the codebase with ast to keep documentation and structural metadata in sync. Sequence diagram for repository maintenance workflow and automated docs/knowledge graphsequenceDiagram
participant GitHub as GitHub
participant RepoMaintenanceWorkflow as repo_maintenance.yml
participant DocsSync as docs_sync.py
participant KnowledgeGraph as generate_knowledge_graph.py
participant Repo as repo
GitHub->>RepoMaintenanceWorkflow: trigger (push/schedule)
RepoMaintenanceWorkflow->>Repo: actions/checkout
RepoMaintenanceWorkflow->>RepoMaintenanceWorkflow: setup Python, Node, uv, cyclonedx-bom
RepoMaintenanceWorkflow->>Repo: ruff check --fix . / ruff format . / prettier --write
RepoMaintenanceWorkflow->>KnowledgeGraph: python tools/generate_knowledge_graph.py
KnowledgeGraph->>KnowledgeGraph: build_knowledge_graph
KnowledgeGraph->>Repo: write docs/knowledge_graph.json
RepoMaintenanceWorkflow->>DocsSync: python tools/docs_sync.py
DocsSync->>DocsSync: generate_api_docs
DocsSync->>Repo: write docs/api/*.md
RepoMaintenanceWorkflow->>Repo: git add -A / git commit / git push
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Review limit reached
Next review available in: 31 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis pull request adds repository governance, GitHub Actions workflows, scheduled maintenance automation, AST-based documentation and knowledge-graph tools, contributor policies, and generated API reference pages. ChangesRepository automation and documentation
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 25
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ai-review.yml:
- Around line 12-15: Add a concurrency configuration to the review job in the
workflow, using a group key based on the pull request or issue number and
enabling cancel-in-progress so newer runs cancel stale model calls. Preserve the
existing review job condition and runner settings.
- Around line 18-21: Update the action reference in the workflow step using
coderabbitai/openai-pr-reviewer so it points to a reviewed full commit SHA
instead of the mutable latest tag, and retain the corresponding release tag in
an inline comment for traceability. Leave the existing environment variables and
workflow behavior unchanged.
- Around line 2-6: Update the workflow trigger and job conditions around
issue_comment so reviews run only for comments on pull requests containing an
explicit supported review command from an authorized commenter. Retain the
existing pull_request triggers, exclude non-PR issue comments and unauthorized
authors, and ensure the authorization check is applied before using GITHUB_TOKEN
or OPENAI_API_KEY.
In @.github/workflows/ci.yml:
- Around line 13-16: Disable persisted checkout credentials by adding
persist-credentials: false to the Checkout repository steps in
.github/workflows/ci.yml lines 13-16, .github/workflows/codeql.yml lines 32-35,
and .github/workflows/pages.yml lines 17-20.
- Around line 14-19: Pin every GitHub Actions uses reference to a reviewed full
commit SHA instead of a mutable tag or branch. Apply this to all action
references in .github/workflows/ci.yml (lines 14-19),
.github/workflows/codeql.yml (lines 32-44), .github/workflows/greetings.yml
(line 17), .github/workflows/labeler.yml (line 14), .github/workflows/pages.yml
(lines 18-31), and .github/workflows/stale.yml (line 15), including CodeQL and
repository-scoped actions; also update the repository-scoped references in
.github/workflows/repo-maintenance.yml, .github/workflows/ai-review.yml,
.github/workflows/security.yml, and .github/workflows/health-dashboard.yml.
- Around line 26-30: Update the CI dependency setup around the “Install
dependencies” and “Run Pytest” steps so the environment used by uv run includes
the dev dependencies, either by requesting the dev extra when invoking pytest or
by synchronizing the project with uv sync; preserve the existing test command
behavior.
In @.github/workflows/repo-maintenance.yml:
- Line 5: Update the branches sequence in the workflow configuration to remove
the spaces immediately inside the brackets, using yamllint-compatible
flow-sequence formatting while preserving the existing main and master branch
values.
- Around line 58-64: Update the “Commit changes” workflow step to check for
staged changes after git add -A and skip git commit only when none exist. Remove
the || echo fallback so failures from git commit propagate and fail the
workflow, while preserving the existing push behavior for successful commits.
- Around line 3-7: Add a workflow-level concurrency configuration alongside the
existing triggers in repo-maintenance.yml, defining a shared concurrency.group
and setting cancel-in-progress to false so push and scheduled runs queue rather
than execute concurrently.
- Line 18: Update the workflow’s actions/checkout, actions/setup-python, and
actions/setup-node references from version tags to their corresponding immutable
full commit SHAs. Preserve each action’s current version and configuration while
ensuring all privileged workflow action references use pinned SHAs.
- Line 32: Pin the maintenance toolchain versions in the workflow steps using
Prettier, uv, ruff, and cyclonedx-bom. Update the npm, pip/uv, and CycloneDX
installation or invocation commands accordingly, using npx --no-install for
Prettier when the locked web package dependency is available; keep all
maintenance commands otherwise unchanged.
- Around line 9-10: Update the workflow-level permissions to default contents
access to read, then add a permissions block under the maintenance job granting
contents write. Keep write access scoped only to jobs.maintenance.
- Around line 17-21: Update the checkout configuration in the repository
maintenance workflow to set persist-credentials to false. Add credential
persistence or equivalent Git authentication only in the final git push step,
ensuring subsequent uv, Ruff, and repository script steps cannot access the
checkout token.
In `@CODE_OF_CONDUCT.md`:
- Around line 39-49: Add an actionable reporting section near “Enforcement
Responsibilities” in the Code of Conduct, identifying the repository’s private
reporting address or reporting-policy link and briefly describing the escalation
and response process. Ensure contributors have a safe, explicit channel for
reporting violations.
In `@docs/api/ev_grid_oracle_city_graph.md`:
- Around line 1-3: Update the heading-generation logic in tools/docs_sync.py so
that, when no module-info section exists, the API section or first API entry
uses H2 rather than emitting H3 directly after the H1. Then regenerate
docs/api/ev_grid_oracle_city_graph.md:1-3,
docs/api/ev_grid_oracle_demand_sim.md:1-3, docs/api/ev_grid_oracle_env.md:1-3,
docs/api/ev_grid_oracle_grid_sim.md:1-3, docs/api/ev_grid_oracle_models.md:1-3,
docs/api/tools_docs_sync.md:1-3,
docs/api/tools_fetch_bangalore_roads_overpass.md:1-3,
docs/api/tools_fetch_osm_roads.md:1-3, and
docs/api/tools_generate_health_dashboard.md:1-3 using the corrected generator.
In `@docs/api/ev_grid_oracle_multi_agent.md`:
- Line 3: Update the documentation generator’s heading-depth logic so top-level
classes, functions, and policies emit H2 headings, while nested class members
remain H3. Regenerate the affected pages:
docs/api/ev_grid_oracle_multi_agent.md:3-3,
docs/api/ev_grid_oracle_oracle_agent.md:3-3,
docs/api/ev_grid_oracle_parsing.md:3-3, docs/api/ev_grid_oracle_personas.md:3-3,
docs/api/ev_grid_oracle_policies.md:3-3,
docs/api/tools_generate_knowledge_graph.md:3-3,
docs/api/tools_prune_osm_geojson.md:3-3, and
docs/api/tools_road_reward_smoke.md:3-3; update each listed top-level heading as
specified, with no direct changes needed to nested member headings.
In `@docs/api/ev_grid_oracle_reward.md`:
- Line 3: Update tools/docs_sync.py to emit an H2 parent before H3 API entries
when no Module Info section exists, then regenerate the affected pages:
docs/api/ev_grid_oracle_reward.md:3-3 before Class: RewardWeights;
docs/api/ev_grid_oracle_reward_hack.md:3-3 before Class: RewardHackDetector;
docs/api/ev_grid_oracle_road_env.md:3-3 before Class: RoadCore;
docs/api/ev_grid_oracle_road_models.md:3-3 before Class: RoadAction;
docs/api/ev_grid_oracle_scenarios.md:3-3 before Class: ScenarioEvent;
docs/api/training_evaluate.md:3-3 before Class: EpisodeMetrics;
docs/api/training_fair_eval.md:3-3 before Function: _binom_two_sided_exact_p;
and docs/api/training_make_plots.md:3-3 before Function: _boxplot_compat.
In `@docs/api/ev_grid_oracle_traffic.md`:
- Line 3: Update the shared heading template in tools/docs_sync.py so generated
API pages preserve the H2 hierarchy by emitting a level-2 parent or making the
first API heading level 2. Regenerate the affected headings at line 3 in
docs/api/ev_grid_oracle_traffic.md,
docs/api/ev_grid_oracle_world_model_verifier.md, docs/api/server_app.md,
docs/api/server_ev_grid_environment.md, docs/api/viz_city_map.md,
docs/api/viz_gradio_demo.md, docs/api/viz_record.md, and
docs/api/viz_record_two_phase.md.
In `@docs/api/server___init__.md`:
- Line 1: Update the title-generation logic in tools/docs_sync.py to qualify
package initializer pages with their package namespace, producing a title such
as server/__init__.py instead of only __init__.py. Then regenerate
docs/api/server___init__.md so its heading reflects the qualified title.
In `@docs/api/server_ev_grid_road_environment.md`:
- Line 3: Update tools/docs_sync.py so generated class and function headings
receive an ## API parent when no module docstring exists, then regenerate
docs/api/server_ev_grid_road_environment.md (3-3),
docs/api/server_road_router.md (3-3), docs/api/server_role_metrics.md (3-3),
docs/api/test_script.md (3-3), docs/api/tests_test_demo_api.md (3-3),
docs/api/tests_test_evaluate_paired.md (3-3),
docs/api/tests_test_fair_eval_mcnemar.md (3-3), and
docs/api/tests_test_models_and_graph.md (3-3) to include the new heading
hierarchy.
In `@docs/api/tools_export_grpo_tensorboard_plots.md`:
- Around line 7-13: Format the pip install and export commands in
docs/api/tools_export_grpo_tensorboard_plots.md as a fenced bash code block (or
consistently indented code block), then regenerate the documentation page so the
rendered commands are copyable.
In `@tools/docs_sync.py`:
- Around line 37-47: Update the heading levels emitted by the AST traversal in
tools/docs_sync.py: change the ClassDef and FunctionDef headings from level 3 to
level 2 so generated API pages remain hierarchically valid when modules lack
docstrings, then regenerate the docs/api output.
- Around line 21-28: Update the output-path construction in the documentation
sync flow around rel_dir and doc_path to preserve the relative directory
structure under docs/api instead of flattening directories with underscores.
Build doc_path from the relative source directory and the converted Markdown
filename so distinct modules such as foo/bar_baz.py and foo_bar/baz.py cannot
overwrite each other.
- Around line 48-49: Update tools/docs_sync.py lines 48-49 to collect read,
parse, and write failures during traversal, continue processing remaining files,
and raise an aggregated failure after traversal instead of only printing errors.
In tools/generate_knowledge_graph.py lines 52-53, collect read and parse
failures and raise them before writing docs/knowledge_graph.json, ensuring both
generators exit unsuccessfully when any source file cannot be processed.
In `@tools/generate_knowledge_graph.py`:
- Around line 27-51: Update the AST traversal around the class/function handling
to recurse with a lexical ancestor path instead of using ast.walk directly.
Build each class and function ID from filepath plus its enclosing class/function
names, connect nested definitions to their immediate containing node (including
methods to their class), and retain the filepath edge only for top-level
definitions.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b464e309-ca76-4c2c-ac5a-5cc08d120573
📒 Files selected for processing (77)
.github/CODEOWNERS.github/dependabot.yml.github/labeler.yml.github/workflows/ai-insights.yml.github/workflows/ai-review.yml.github/workflows/ci.yml.github/workflows/codeql.yml.github/workflows/greetings.yml.github/workflows/health-dashboard.yml.github/workflows/labeler.yml.github/workflows/pages.yml.github/workflows/repo-maintenance.yml.github/workflows/stale.yml.gitignoreCODE_OF_CONDUCT.mdCONTRIBUTING.mddocs/api/ev_grid_oracle___init__.mddocs/api/ev_grid_oracle_bescom_feed.mddocs/api/ev_grid_oracle_city_graph.mddocs/api/ev_grid_oracle_demand_sim.mddocs/api/ev_grid_oracle_env.mddocs/api/ev_grid_oracle_grid_sim.mddocs/api/ev_grid_oracle_models.mddocs/api/ev_grid_oracle_multi_agent.mddocs/api/ev_grid_oracle_oracle_agent.mddocs/api/ev_grid_oracle_parsing.mddocs/api/ev_grid_oracle_personas.mddocs/api/ev_grid_oracle_policies.mddocs/api/ev_grid_oracle_reward.mddocs/api/ev_grid_oracle_reward_hack.mddocs/api/ev_grid_oracle_road_env.mddocs/api/ev_grid_oracle_road_models.mddocs/api/ev_grid_oracle_scenarios.mddocs/api/ev_grid_oracle_traffic.mddocs/api/ev_grid_oracle_world_model_verifier.mddocs/api/server___init__.mddocs/api/server_app.mddocs/api/server_ev_grid_environment.mddocs/api/server_ev_grid_road_environment.mddocs/api/server_road_router.mddocs/api/server_role_metrics.mddocs/api/test_script.mddocs/api/tests___init__.mddocs/api/tests_test_demo_api.mddocs/api/tests_test_env_determinism.mddocs/api/tests_test_evaluate_paired.mddocs/api/tests_test_fair_eval_mcnemar.mddocs/api/tests_test_models_and_graph.mddocs/api/tests_test_parsing.mddocs/api/tests_test_policies_collapse.mddocs/api/tests_test_reward.mddocs/api/tests_test_world_model_verifier.mddocs/api/tools___init__.mddocs/api/tools_build_road_graph.mddocs/api/tools_build_roads_render.mddocs/api/tools_docs_sync.mddocs/api/tools_export_grpo_tensorboard_plots.mddocs/api/tools_fetch_bangalore_roads_overpass.mddocs/api/tools_fetch_osm_roads.mddocs/api/tools_generate_health_dashboard.mddocs/api/tools_generate_knowledge_graph.mddocs/api/tools_prune_osm_geojson.mddocs/api/tools_road_reward_smoke.mddocs/api/tools_sync_space_to_hub.mddocs/api/tools_write_eval_snapshot.mddocs/api/training___init__.mddocs/api/training_evaluate.mddocs/api/training_fair_eval.mddocs/api/training_make_plots.mddocs/api/viz___init__.mddocs/api/viz_city_map.mddocs/api/viz_gradio_demo.mddocs/api/viz_record.mddocs/api/viz_record_two_phase.mddocs/knowledge_graph.jsontools/docs_sync.pytools/generate_knowledge_graph.py
💤 Files with no reviewable changes (2)
- .github/workflows/ai-insights.yml
- .github/workflows/health-dashboard.yml
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: frontend-quality
- GitHub Check: python-quality
⚠️ CI failures not shown inline (2)
GitHub Actions: AI Review / 0_review.txt: feat: Implement autonomous repository management workflows and scripts
Conclusion: failure
##[group]GITHUB_TOKEN Permissions
Contents: read
Metadata: read
PullRequests: write
##[endgroup]
Secret source: Actions
Prepare workflow directory
Prepare all required actions
Getting action download info
##[error]Unable to resolve action `coderabbitai/openai-pr-reviewer`, not found
GitHub Actions: AI Review / review: feat: Implement autonomous repository management workflows and scripts
Conclusion: failure
##[group]GITHUB_TOKEN Permissions
Contents: read
Metadata: read
PullRequests: write
##[endgroup]
Secret source: Actions
Prepare workflow directory
Prepare all required actions
Getting action download info
##[error]Unable to resolve action `coderabbitai/openai-pr-reviewer`, not found
🧰 Additional context used
🪛 ast-grep (0.45.0)
tools/docs_sync.py
[warning] 15-15: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(filepath, "r", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(open-filename-from-request)
[warning] 29-29: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(doc_path, "w", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(open-filename-from-request)
tools/generate_knowledge_graph.py
[warning] 17-17: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(filepath, "r", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(open-filename-from-request)
🪛 LanguageTool
CONTRIBUTING.md
[style] ~24-~24: Consider using a less common alternative to make your writing sound more unique and professional.
Context: ...int, you're ready to make your changes. Feel free to ask for help; everyone is a beginner at...
(FEEL_FREE_TO_STYLE_ME)
CODE_OF_CONDUCT.md
[style] ~32-~32: Try using a synonym here to strengthen your wording.
Context: ...ind * Trolling, insulting or derogatory comments, and personal or political attacks * Pu...
(COMMENT_REMARK)
🪛 markdownlint-cli2 (0.23.2)
docs/api/ev_grid_oracle_road_env.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/server_ev_grid_environment.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_generate_knowledge_graph.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_fetch_osm_roads.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_docs_sync.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_evaluate_paired.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/server_ev_grid_road_environment.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_parsing.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_personas.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_road_models.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_road_reward_smoke.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/test_script.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_fetch_bangalore_roads_overpass.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_models_and_graph.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/training_evaluate.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_world_model_verifier.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_fair_eval_mcnemar.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_grid_sim.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_scenarios.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_parsing.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_build_road_graph.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/viz_gradio_demo.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_city_graph.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_multi_agent.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_oracle_agent.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_policies.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_demo_api.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_demand_sim.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/training_fair_eval.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_reward.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_env.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_bescom_feed.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_world_model_verifier.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_build_roads_render.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/viz_record_two_phase.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/viz_city_map.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_prune_osm_geojson.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_traffic.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/server_road_router.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_reward_hack.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/training_make_plots.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/viz_record.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tools_generate_health_dashboard.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/server_role_metrics.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/tests_test_reward.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/ev_grid_oracle_models.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
docs/api/server_app.md
[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🪛 YAMLlint (1.37.1)
.github/workflows/ci.yml
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 7-7: too many spaces inside brackets
(brackets)
[error] 7-7: too many spaces inside brackets
(brackets)
.github/workflows/codeql.yml
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 7-7: too many spaces inside brackets
(brackets)
[error] 7-7: too many spaces inside brackets
(brackets)
.github/workflows/repo-maintenance.yml
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 5-5: too many spaces inside brackets
(brackets)
🪛 zizmor (1.29.0)
.github/workflows/ci.yml
[warning] 13-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 1-31: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 19-19: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 10-10: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-7: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/ai-review.yml
[error] 10-10: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level
(excessive-permissions)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 10-10: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 13-13: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 2-6: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/codeql.yml
[warning] 32-35: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 1-47: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 33-33: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 38-38: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 44-44: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 17-17: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[warning] 3-9: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/pages.yml
[warning] 17-20: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 10-10: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level
(excessive-permissions)
[error] 3-7: use of fundamentally insecure workflow trigger (dangerous-triggers): workflow_run is almost always used insecurely
(dangerous-triggers)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 23-23: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 31-31: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 10-10: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 13-13: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-7: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/greetings.yml
[error] 10-10: overly broad permissions (excessive-permissions): issues: write is overly broad at the workflow level
(excessive-permissions)
[error] 11-11: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level
(excessive-permissions)
[error] 3-7: use of fundamentally insecure workflow trigger (dangerous-triggers): pull_request_target is almost always used insecurely
(dangerous-triggers)
[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 10-10: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 14-14: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-7: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/stale.yml
[error] 8-8: overly broad permissions (excessive-permissions): issues: write is overly broad at the workflow level
(excessive-permissions)
[error] 9-9: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level
(excessive-permissions)
[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 8-8: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 12-12: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-5: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/labeler.yml
[error] 8-8: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level
(excessive-permissions)
[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 8-8: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 11-11: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 2-4: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
.github/workflows/repo-maintenance.yml
[warning] 17-21: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 10-10: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level
(excessive-permissions)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 24-24: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 29-29: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[warning] 10-10: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 13-13: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-7: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
[warning] 32-32: ad-hoc installation of packages (adhoc-packages): installs a package outside of a lockfile
(adhoc-packages)
🔇 Additional comments (13)
.github/CODEOWNERS (1)
1-1: LGTM!.github/dependabot.yml (1)
7-10: 🗄️ Data Integrity & IntegrationVerify that
pipupdates keepuv.locksynchronized.The repository uses a root
pyproject.tomlanduv.lock.CONTRIBUTING.md:15-20directs contributors to useuv sync --all-extras. Confirm that a Dependabot update changes both the dependency declarations and the lockfile, and that the generated PR passes dependency checks. Otherwise, the declared and resolved versions can diverge..github/labeler.yml (1)
1-24: 🎯 Functional CorrectnessVerify the labeler configuration schema.
This file uses the
anyrule form. Confirm that.github/workflows/labeler.ymlinvokes anactions/labelerversion that accepts this form and loads this file. Otherwise, the workflow can run without applying thecore,frontend,tests,docs, andcilabels..gitignore (1)
34-34: LGTM!CONTRIBUTING.md (1)
1-3: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winReplace template-specific repository and branch commands.
CONTRIBUTING.mdstill hard-codesNITISH-R-G/OpenEnv.git,master, and325-add-japanese-translations, but this repository isev-grid-oracleonmain. Use that upstream repo name and default branch, and replace the specific checkout with a generic<feature-branch>placeholder.Example adjustment
-git push --set-upstream origin 325-add-japanese-translations +git push --set-upstream origin <feature-branch>> Likely an incorrect or invalid review comment..github/workflows/pages.yml (1)
4-15: 🔒 Security & PrivacyNo change needed for Pages deployment scope.
Repository Health Dashboarddoes not deploy to Pages; it only uploads thehealth-dashboardartifact.> Likely an incorrect or invalid review comment.docs/api/tools_sync_space_to_hub.md (1)
1-17: LGTM!docs/api/tools_write_eval_snapshot.md (1)
1-7: LGTM!docs/api/training___init__.md (1)
1-6: LGTM!docs/api/viz___init__.md (1)
1-2: LGTM!.github/workflows/repo-maintenance.yml (1)
49-64: 🩺 Stability & AvailabilityVerify generated output is idempotent before self-pushing.
This workflow runs on pushes to
mainandmaster, then pushes generated documentation, graph, and SBOM changes. If any generator emits timestamps, UUIDs, or unstable ordering, each run can create another commit and trigger another maintenance run. Generate the outputs twice from the same revision and compare them. Normalize or exclude volatile fields.docs/api/tests___init__.md (1)
1-2: LGTM!docs/api/tests_test_env_determinism.md (1)
1-14: LGTM!
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
| issue_comment: | ||
| types: [created] |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repo files:\n'
git ls-files | rg '(^|/)(ai-review\.yml|.*workflow.*|.*workflows.*)$' || true
printf '\nWorkflow excerpt:\n'
if [ -f .github/workflows/ai-review.yml ]; then
nl -ba .github/workflows/ai-review.yml | sed -n '1,80p'
fi
printf '\nSearch for issue_comment usage:\n'
rg -n "issue_comment|pull_request|pull-requests: write|openai-pr-reviewer|from.*secrets|OPENAI_API_KEY|GITHUB_TOKEN|permissions:" .github/workflows || true
printf '\nGitHub event/docs equivalent references in repo (if any):\n'
rg -n "issue|comment" .github/workflows README.md . 2>/dev/null | head -200 || trueRepository: NITISH-R-G/ev-grid-oracle
Length of output: 582
🌐 Web query:
GitHub Actions issues event issue_comment pull_request comment author permission pull request
💡 Result:
To handle GitHub Actions workflows triggered by comments on pull requests, it is important to distinguish between the event type, the necessary permissions, and the security context of the PR author. Event Triggering and Context The issue_comment event is the standard trigger for workflows running on comments, covering both issues and pull requests [1][2]. Because this event is shared, you must filter your workflow to execute only when the comment originates from a pull request [1]. You can perform this check using a conditional in your workflow: jobs: pr_commented: if: github.event.issue.pull_request!= null runs-on: ubuntu-latest steps: - name: A comment on a PR run: echo "PR number is ${{ github.event.issue.number }}" Permission Requirements When your workflow needs to interact with pull requests—such as posting comments or adding reactions—you must explicitly grant the necessary permissions in your workflow configuration [3]. Contrary to what the REST API path (/repos/…/issues/comments/…) might imply, comments on pull requests belong to the pull-requests resource [3]. Therefore, you should grant: permissions: pull-requests: write Granting only issues: write is often insufficient or incorrect for pull request operations, and may result in 403 Forbidden errors [3]. Security Considerations If you need to restrict your workflow to specific users (e.g., the PR author or users with certain permissions), you can use expressions based on the GitHub context [4]. 1. Restricting by Author: You can gate the job using an if condition that checks the PR author: if: github.event.pull_request.user.login == 'target-username' 2. Security and Forks: Workflows triggered by issue_comment run from the default branch, which is generally secure [2][3]. However, if you use the pull_request_target event to handle PRs from forks, be aware that it runs with elevated permissions and access to secrets [5][6]. You must carefully validate that the logic does not inadvertently execute untrusted code or expose sensitive information [5][7]. For complex requirements, such as running scripts based on specific comment commands, consider checking the user's author_association (e.g., OWNER, COLLABORATOR) to ensure only trusted users can trigger sensitive automation [8][4].
Citations:
- 1: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows
- 2: https://github.com/marketplace/actions/pull-request-comment-branch
- 3: Fix rcgitbot_please_test token permissions for PR comments RevenueCat/purchases-ios#6655
- 4: https://jackdog668-claude-code.mintlify.app/integrations/github-actions
- 5: https://docs.github.com/en/actions/reference/security/securely-using-pull_request_target
- 6: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions
- 7: https://netomi.github.io/eclipse/2024/08/21/adding-comments-to-pr.html
- 8: https://github.com/nwtgck/actions-comment-run/blob/6bea6fb49b8a3e2253f5e2e9ebfded12caf17113/README.md
🌐 Web query:
GitHub Actions pull_request_target issue_comment authorized actors repository permissions
💡 Result:
In GitHub Actions, the pull_request_target event and other triggers like issue_comment are considered privileged because they execute within the context of the base repository rather than the pull request's source branch [1][2][3]. This creates a significant security risk known as a "pwn request" if the workflow is configured to check out and execute untrusted code from a fork [4][2]. Key Security Considerations and Permissions: 1. Privileged Context: Unlike the standard pull_request trigger—which runs in an unprivileged environment with read-only tokens and no access to repository secrets when triggered from a fork—pull_request_target and issue_comment have access to the base repository's secrets and a read/write GITHUB_TOKEN by default [1][2][5]. 2. Authorized Actors: On public repositories, pull_request_target, issue_comment, and similar event-triggered workflows can be triggered by any user who can open a pull request, comment, or interact with the repository, regardless of their collaborator status [6][2]. This means an external attacker can trigger code that runs with your repository's full privileges [2][3]. 3. The "Pwn Request" Risk: The primary danger arises when a workflow running under these triggers automatically checks out the pull request head (the attacker-controlled code) and executes it (e.g., via build scripts, npm install, or other language-specific package managers) [4][2]. Because the workflow runs in the privileged base context, this code can exfiltrate secrets or modify the repository [1][3]. 4. Mitigation Strategies: - Avoid executing untrusted code: Never check out and run code from a pull request or comment context within a privileged workflow [7][2]. - Restrict triggers: Use the if condition to limit workflows to authorized actors (e.g., if: github.event.comment.author_association == 'MEMBER') [6][2]. - Use least privilege: Always define explicit permissions for the GITHUB_TOKEN at the job or workflow level to minimize potential impact if the workflow is compromised [1][8]. - Prefer unprivileged triggers: Whenever possible, use the standard pull_request trigger to handle untrusted code [2][9]. If a privileged operation is required, consider a two-step process: an unprivileged pull_request workflow to perform the work and store artifacts, followed by a separate workflow_run workflow to consume those artifacts in a privileged environment [7][2]. As of June 2026, GitHub has introduced safer defaults for actions/checkout when used with pull_request_target to help block the accidental checkout of untrusted fork heads, though users should still treat opting out of these protections as a serious security decision [4].
Citations:
- 1: https://docs.github.com/en/actions/reference/security/securely-using-pull_request_target
- 2: https://github.com/github/awesome-copilot/blob/main/skills/github-actions-hardening/references/triggers-and-privilege.md
- 3: https://securitylab.github.com/resources/github-actions-new-patterns-and-mitigations/
- 4: https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/
- 5: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
- 6: Enhance
dangerous-triggers: flagissue_commentas a dangerous trigger zizmorcore/zizmor#1606 - 7: https://codeql.github.com/codeql-query-help/actions/actions-untrusted-checkout-critical/
- 8: https://github.com/github/docs/blob/main/content/actions/tutorials/authenticate-with-github_token.md
- 9: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/securely-using-pull_request_target
🏁 Script executed:
#!/bin/bash
set -u
printf 'Workflow excerpt:\n'
sed -n '1,80p' .github/workflows/ai-review.yml 2>/dev/null | python3 - <<'PS'
from pathlib import Path
p = Path('/tmp/fake')
text = __import__('sys', fromlist=['stdin']).stdin.read().splitlines()
for i, line in enumerate(text, 1):
print(f'{i:4d} {line}')
PS
printf '\nRelevant workflow search:\n'
grep -RInE 'on:|pull_request:|issue_comment:|pull-requests:|contents:|permissions:|GITHUB_TOKEN|OPENAI_API_KEY|coderabbitai/openai-pr-reviewer|github.event.issue.pull_request|github.event.comment|author_association|comment\.body|types:' .github/workflows/ai-review.yml .github/workflows || true
printf '\nChanged files summary:\n'
git diff --stat HEAD~1..HEAD 2>/dev/null || git diff --stat 2>/dev/null || trueRepository: NITISH-R-G/ev-grid-oracle
Length of output: 10393
🏁 Script executed:
#!/bin/bash
set -u
printf 'Workflow excerpt:\n'
awk '{printf "%4d: %s\n", NR, $0}' .github/workflows/ai-review.yml
printf '\nPython read-only invariant check:\n'
python3 - <<'PY'
from pathlib import Path
from urllib.parse import urlparse
p = Path(".github/workflows/ai-review.yml")
text = p.read_text()
if "issue_comment:" in text and "types: [created]" in text:
print("issue_comment created trigger present")
else:
print("issue_comment created trigger absent")
if "GITHUB_TOKEN:" in text and "OPENAI_API_KEY:" in text:
print("workflow passes GITHUB_TOKEN and OPENAI_API_KEY to action")
if "coderabbitai/openai-pr-reviewer@latest" in text:
print("mutable action tag: coderabbitai/openai-pr-reviewer@latest")
url = urlparse("https://github.com/coderabbitai/openai-pr-reviewer")
if url.path.endswith("/openai-pr-reviewer") and url.hostname in ("github.com", "github.io"):
print("action_name=coderabbitai/openai-pr-reviewer")
print("full_ref=latest")
PYRepository: NITISH-R-G/ev-grid-oracle
Length of output: 1044
Gate comment-triggered reviews to authorized PR commands.
issue_comment: created runs for every new issue comment. The job currently filters only on github.event.sender.type != 'Bot', so any commenter can start a run with GITHUB_TOKEN and OPENAI_API_KEY. Restrict this path to pull-request comments with an explicit review command and an authorized author.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 2-6: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ai-review.yml around lines 2 - 6, Update the workflow
trigger and job conditions around issue_comment so reviews run only for comments
on pull requests containing an explicit supported review command from an
authorized commenter. Retain the existing pull_request triggers, exclude non-PR
issue comments and unauthorized authors, and ensure the authorization check is
applied before using GITHUB_TOKEN or OPENAI_API_KEY.
| jobs: | ||
| review: | ||
| runs-on: ubuntu-latest | ||
| if: ${{ github.event.sender.type != 'Bot' }} |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
Cancel stale review runs.
pull_request.synchronize and issue_comment.created can start multiple jobs before the previous model call finishes. Add a concurrency group keyed by the pull request or issue number and set cancel-in-progress: true. Otherwise, stale or duplicate reviews can consume API quota and post outdated results.
Proposed concurrency setting
+concurrency:
+ group: ai-review-${{ github.event.pull_request.number || github.event.issue.number }}
+ cancel-in-progress: true📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| jobs: | |
| review: | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.sender.type != 'Bot' }} | |
| concurrency: | |
| group: ai-review-${{ github.event.pull_request.number || github.event.issue.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| review: | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.sender.type != 'Bot' }} |
🧰 Tools
🪛 zizmor (1.29.0)
[info] 13-13: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ai-review.yml around lines 12 - 15, Add a concurrency
configuration to the review job in the workflow, using a group key based on the
pull request or issue number and enabling cancel-in-progress so newer runs
cancel stale model calls. Preserve the existing review job condition and runner
settings.
Source: Linters/SAST tools
| uses: coderabbitai/openai-pr-reviewer@latest | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
sed -n '1,80p' .github/workflows/ai-review.yml 2>/dev/null || true
echo
echo "== references to action and permissions/secrets =="
rg -n "coderabbitai/openai-pr-reviewer|GITHUB_TOKEN|OPENAI_API_KEY|permissions:|pull-requests|contents|id-token|GITHUB_TOKEN" .github/workflows/ai-review.yml || true
echo
echo "== GitHub API resolve for coderabbitai/openai-pr-reviewer refs/tags/latest =="
tmpdir="$(mktemp -d)"
cd "$tmpdir"
if command -v gh >/dev/null 2>&1; then
echo "gh available"
gh api repos/coderabbitai/openai-pr-reviewer/git/ref/tags/latest --jq '{ref, object_type: .object.type, object_sha: .object.sha}' || true
latest_sha="$(gh api repos/coderabbitai/openai-pr-reviewer/git/ref/tags/latest --jq '.object.sha')" || true
echo "latest ref object sha: $latest_sha"
if [ -n "$latest_sha" ]; then
obj_type="$(gh api repos/coderabbitai/openai-pr-reviewer/git/tags/${latest_sha} --jq '.type' 2>/dev/null || true)"
echo "tag object type: $obj_type"
if [ "$obj_type" = "tag" ]; then
deref="$(gh api repos/coderabbitai/openai-pr-reviewer/git/tags/${latest_sha} --jq '.object.sha')" || true
echo "dereferenced commit sha: $deref"
gh api repos/coderabbitai/openai-pr-reviewer/commits/${deref} >/dev/null && echo "dereferenced commit exists" || echo "dereferenced commit missing"
elif [ "$obj_type" = "commit" ]; then
echo "lightweight commit object exists"
gh api repos/coderabbitai/openai-pr-reviewer/commits/${latest_sha} >/dev/null && echo "latest object commit exists" || echo "latest object commit missing"
else
echo "unexpected tag object type"
fi
fi
else
echo "gh not available"
fi
echo
echo "== available workflow files listing =="
git ls-files '.github/workflows/*'Repository: NITISH-R-G/ev-grid-oracle
Length of output: 1457
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
sed -n '1,120p' .github/workflows/ai-review.yml 2>/dev/null || true
echo
echo "== references to action and permissions/secrets =="
rg -n "coderabbitai/openai-pr-reviewer|GITHUB_TOKEN|OPENAI_API_KEY|permissions:|pull-requests|contents|id-token|GITHUB_TOKEN" .github/workflows/ai-review.yml || true
echo
echo "== GitHub API resolve for coderabbitai/openai-pr-reviewer refs/tags/latest =="
tmpdir="$(mktemp -d)"
cd "$tmpdir"
if command -v gh >/dev/null 2>&1; then
echo "gh available"
gh api repos/coderabbitai/openai-pr-reviewer/git/ref/tags/latest --jq '{ref, object_type: .object.type, object_sha: .object.sha}' || true
latest_sha="$(gh api repos/coderabbitai/openai-pr-reviewer/git/ref/tags/latest --jq '.object.sha')" || true
echo "latest ref object sha: $latest_sha"
if [ -n "$latest_sha" ]; then
obj_type="$(gh api repos/coderabbitai/openai-pr-reviewer/git/tags/${latest_sha} --jq '.type' 2>/dev/null || true)"
echo "tag object type: $obj_type"
if [ "$obj_type" = "tag" ]; then
deref="$(gh api repos/coderabbitai/openai-pr-reviewer/git/tags/${latest_sha} --jq '.object.sha')" || true
echo "dereferenced commit sha: $deref"
gh api repos/coderabbitai/openai-pr-reviewer/commits/${deref} >/dev/null && echo "dereferenced commit exists" || echo "dereferenced commit missing"
elif [ "$obj_type" = "commit" ]; then
echo "lightweight commit object exists"
gh api repos/coderabbitai/openai-pr-reviewer/commits/${latest_sha} >/dev/null && echo "latest object commit exists" || echo "latest object commit missing"
else
echo "unexpected tag object type"
fi
fi
else
echo "gh not available"
fi
echo
echo "== available workflow files listing =="
git ls-files '.github/workflows/*'Repository: NITISH-R-G/ev-grid-oracle
Length of output: 1457
Pin the third-party action to an immutable commit.
This workflow runs in pull_request/issue_comment context and passes GITHUB_TOKEN and OPENAI_API_KEY. coderabbitai/openai-pr-reviewer@latest is a mutable ref; replace it with a reviewed full commit SHA while keeping the release tag in a comment.
Proposed action reference
- uses: coderabbitai/openai-pr-reviewer@latest
+ uses: coderabbitai/openai-pr-reviewer@<40-character-reviewed-commit-sha> # vX.Y.Z🧰 Tools
🪛 zizmor (1.29.0)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ai-review.yml around lines 18 - 21, Update the action
reference in the workflow step using coderabbitai/openai-pr-reviewer so it
points to a reviewed full commit SHA instead of the mutable latest tag, and
retain the corresponding release tag in an inline comment for traceability.
Leave the existing environment variables and workflow behavior unchanged.
Source: Linters/SAST tools
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| lfs: true |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Do not persist checkout credentials.
These jobs do not need Git credentials after checkout. CI only installs and runs tests. CodeQL uses its own GitHub Actions token context. Pages passes tokens directly to its download and deployment actions. Set persist-credentials: false to prevent later commands or actions from reading the token from Git configuration.
.github/workflows/ci.yml#L13-L16: addpersist-credentials: false..github/workflows/codeql.yml#L32-L35: addpersist-credentials: false..github/workflows/pages.yml#L17-L20: addpersist-credentials: false.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 13-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
📍 Affects 3 files
.github/workflows/ci.yml#L13-L16(this comment).github/workflows/codeql.yml#L32-L35.github/workflows/pages.yml#L17-L20
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 13 - 16, Disable persisted checkout
credentials by adding persist-credentials: false to the Checkout repository
steps in .github/workflows/ci.yml lines 13-16, .github/workflows/codeql.yml
lines 32-35, and .github/workflows/pages.yml lines 17-20.
Source: Linters/SAST tools
| uses: actions/checkout@v4 | ||
| with: | ||
| lfs: true | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
while read -r repository tag; do
printf '%s@%s = ' "$repository" "$tag"
gh api "repos/$repository/commits/$tag" --jq '.sha'
done <<'EOF'
actions/checkout v4
actions/setup-python v5
github/codeql-action/init v3
github/codeql-action/analyze v3
actions/first-interaction v1
actions/labeler v5
actions/download-artifact v4
peaceiris/actions-gh-pages v4
actions/stale v9
EOFRepository: NITISH-R-G/ev-grid-oracle
Length of output: 455
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "workflow usages:"
rg -n 'uses:\s*[^[:space:]]+' .github/workflows || true
echo
echo "git refs for relevant tags:"
for ref in refs/tags/v4 refs/tags/v5 refs/tags/v3 refs/tags/v2 refs/tags/v1; do
git cat-file -t "$ref" 2>/dev/null && git rev-parse "$ref"
doneRepository: NITISH-R-G/ev-grid-oracle
Length of output: 2386
🌐 Web query:
github/codeql-action GitHub repository v3 tag
💡 Result:
The github/codeql-action repository maintains a v3 release series, which is currently supported alongside the newer v4 series [1][2]. The v3 tag is not a single point-in-time release but rather a major version branch that receives ongoing updates, bug fixes, and feature improvements [1][2]. Key details regarding CodeQL Action v3 include: - Purpose: The CodeQL Action series (v2, v3, v4) differentiates between underlying Node.js runtime versions [3][4]. Specifically, v3 runs on Node 20 [3][4]. - Usage: GitHub recommends that users reference the major version tag (e.g., @v3 or @v4) in their workflow files to automatically receive the latest updates, patches, and CodeQL CLI version improvements within that major version [1][2]. - Versioning: Individual releases within the v3 series follow semantic versioning, such as v3.37.4 [5][6]. - Support Status: v3 remains a supported major version [1][2]. GitHub typically advises using the latest major version (currently v4) for new setups, while existing workflows can continue using v3 [1][2]. To see the specific releases available within the v3 series, you can view the official releases page of the repository [5].
Citations:
- 1: https://github.com/github/codeql-action/tree/releases/v3
- 2: https://github.com/github/codeql-action
- 3: https://github.com/github/codeql-action/blob/1c60bf167bf7381660d6beef09ff28ef424ddebf/README.md
- 4: https://github.com/github/codeql-action/blob/v3.27.4/CHANGELOG.md
- 5: https://github.com/github/codeql-action/releases
- 6: https://github.com/github/codeql-action/blob/main/CHANGELOG.md
Pin all GitHub Actions to immutable commits.
Mutable tags can switch to different action code without a repository change. Pin each uses: reference to a reviewed full commit SHA, including the CodeQL actions and the repository-scoped references in .github/workflows/repo-maintenance.yml, .github/workflows/ai-review.yml, .github/workflows/security.yml, and .github/workflows/health-dashboard.yml.
🧰 Tools
🪛 zizmor (1.29.0)
[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 19-19: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
📍 Affects 6 files
.github/workflows/ci.yml#L14-L19(this comment).github/workflows/codeql.yml#L32-L44.github/workflows/greetings.yml#L17-L17.github/workflows/labeler.yml#L14-L14.github/workflows/pages.yml#L18-L31.github/workflows/stale.yml#L15-L15
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 14 - 19, Pin every GitHub Actions uses
reference to a reviewed full commit SHA instead of a mutable tag or branch.
Apply this to all action references in .github/workflows/ci.yml (lines 14-19),
.github/workflows/codeql.yml (lines 32-44), .github/workflows/greetings.yml
(line 17), .github/workflows/labeler.yml (line 14), .github/workflows/pages.yml
(lines 18-31), and .github/workflows/stale.yml (line 15), including CodeQL and
repository-scoped actions; also update the repository-scoped references in
.github/workflows/repo-maintenance.yml, .github/workflows/ai-review.yml,
.github/workflows/security.yml, and .github/workflows/health-dashboard.yml.
Source: Linters/SAST tools
| Hackathon requirement: committed plots from a *real* GRPO run. After `trainer.train()` in | ||
| `training/train_grpo.ipynb`, copy `ev_oracle_grpo_road/` from Colab (or run locally), then: | ||
|
|
||
| pip install tensorboard matplotlib | ||
| python tools/export_grpo_tensorboard_plots.py --logdir ev_oracle_grpo_road --out-dir artifacts | ||
|
|
||
| Writes e.g. artifacts/grpo_loss.png and artifacts/grpo_reward.png (filenames depend on tags found). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Render the shell commands as a code block.
Lines 10-11 use two-space indentation. Use a fenced bash block or four-space indentation in the source module docstring. Then regenerate this page so users can copy the commands reliably.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/api/tools_export_grpo_tensorboard_plots.md` around lines 7 - 13, Format
the pip install and export commands in
docs/api/tools_export_grpo_tensorboard_plots.md as a fenced bash code block (or
consistently indented code block), then regenerate the documentation page so the
rendered commands are copyable.
| # Create a path-safe filename to prevent collisions (e.g., server_app.md instead of just app.md) | ||
| rel_dir = os.path.relpath(dirpath, root_dir) | ||
| if rel_dir == ".": | ||
| safe_filename = file.replace(".py", ".md") | ||
| else: | ||
| safe_filename = f"{rel_dir.replace(os.sep, '_')}_{file.replace('.py', '.md')}" | ||
|
|
||
| doc_path = os.path.join("docs/api", safe_filename) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use a collision-free output path.
foo/bar_baz.py and foo_bar/baz.py both produce foo_bar_baz.md. The later traversal overwrites the earlier API page. Preserve the relative directory structure under docs/api instead of joining path components with underscores.
Proposed fix
- rel_dir = os.path.relpath(dirpath, root_dir)
- if rel_dir == ".":
- safe_filename = file.replace(".py", ".md")
- else:
- safe_filename = f"{rel_dir.replace(os.sep, '_')}_{file.replace('.py', '.md')}"
-
- doc_path = os.path.join("docs/api", safe_filename)
+ rel_path = os.path.relpath(filepath, root_dir)
+ doc_path = os.path.join(
+ "docs/api", os.path.splitext(rel_path)[0] + ".md"
+ )
+ os.makedirs(os.path.dirname(doc_path), exist_ok=True)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/docs_sync.py` around lines 21 - 28, Update the output-path construction
in the documentation sync flow around rel_dir and doc_path to preserve the
relative directory structure under docs/api instead of flattening directories
with underscores. Build doc_path from the relative source directory and the
converted Markdown filename so distinct modules such as foo/bar_baz.py and
foo_bar/baz.py cannot overwrite each other.
| for node in ast.walk(tree): | ||
| if isinstance(node, ast.ClassDef): | ||
| doc_file.write(f"### Class: `{node.name}`\n\n") | ||
| class_doc = ast.get_docstring(node) | ||
| if class_doc: | ||
| doc_file.write(f"{class_doc}\n\n") | ||
| elif isinstance(node, ast.FunctionDef): | ||
| doc_file.write(f"### Function: `{node.name}`\n\n") | ||
| func_doc = ast.get_docstring(node) | ||
| if func_doc: | ||
| doc_file.write(f"{func_doc}\n\n") |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Generate level-2 API headings.
The generator writes ### headings directly after the document H1 when a module has no docstring. This produces MD001 violations in generated pages such as docs/api/tests_test_parsing.md. Write ## Class and ## Function headings, then regenerate docs/api.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/docs_sync.py` around lines 37 - 47, Update the heading levels emitted
by the AST traversal in tools/docs_sync.py: change the ClassDef and FunctionDef
headings from level 3 to level 2 so generated API pages remain hierarchically
valid when modules lack docstrings, then regenerate the docs/api output.
Source: Linters/SAST tools
| except Exception as e: | ||
| print(f"Error parsing {filepath}: {e}") |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Fail generation when a source file cannot be processed.
Both generators print an error and exit successfully. Scheduled maintenance can then commit incomplete documentation or a partial knowledge graph.
tools/docs_sync.py#L48-L49: collect read, parse, and write failures, then raise after traversal.tools/generate_knowledge_graph.py#L52-L53: collect read and parse failures, then raise before writingdocs/knowledge_graph.json.
📍 Affects 2 files
tools/docs_sync.py#L48-L49(this comment)tools/generate_knowledge_graph.py#L52-L53
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/docs_sync.py` around lines 48 - 49, Update tools/docs_sync.py lines
48-49 to collect read, parse, and write failures during traversal, continue
processing remaining files, and raise an aggregated failure after traversal
instead of only printing errors. In tools/generate_knowledge_graph.py lines
52-53, collect read and parse failures and raise them before writing
docs/knowledge_graph.json, ensuring both generators exit unsuccessfully when any
source file cannot be processed.
| for node in ast.walk(tree): | ||
| if isinstance(node, ast.ClassDef): | ||
| class_id = f"{filepath}::{node.name}" | ||
| graph["nodes"].append( | ||
| {"id": class_id, "type": "class", "label": node.name} | ||
| ) | ||
| graph["edges"].append( | ||
| { | ||
| "source": filepath, | ||
| "target": class_id, | ||
| "relation": "contains", | ||
| } | ||
| ) | ||
| elif isinstance(node, ast.FunctionDef): | ||
| func_id = f"{filepath}::{node.name}" | ||
| graph["nodes"].append( | ||
| {"id": func_id, "type": "function", "label": node.name} | ||
| ) | ||
| graph["edges"].append( | ||
| { | ||
| "source": filepath, | ||
| "target": func_id, | ||
| "relation": "contains", | ||
| } | ||
| ) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Model lexical containment and unique node IDs.
ast.walk visits class methods and nested functions, but this code connects every function to filepath. It also uses filepath::{node.name} for every function ID. Two classes with a method of the same name produce duplicate IDs, and methods are not connected to their containing class.
Traverse the AST recursively. Include the enclosing class or function path in each node ID. Connect a method node to its class node.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tools/generate_knowledge_graph.py` around lines 27 - 51, Update the AST
traversal around the class/function handling to recurse with a lexical ancestor
path instead of using ast.walk directly. Build each class and function ID from
filepath plus its enclosing class/function names, connect nested definitions to
their immediate containing node (including methods to their class), and retain
the filepath edge only for top-level definitions.
…lities - Setup community guidelines and templates - Configure AI PR reviewer action - Configure stale issues and greetings automations - Configure PR labeler based on file paths - Add codeql security analysis workflow - Add unified repo-maintenance workflow for formatting, linting, docs, kg, and sboms - Create ast-based automated docs syncing tool - Create ast-based automated knowledge graph generation tool - Setup dependabot for pip, npm, and gh-actions - Separate GitHub Pages deployment into its own workflow - Configure robust testing CI Co-authored-by: NITISH-R-G <225521762+NITISH-R-G@users.noreply.github.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…lities - Setup community guidelines and templates - Configure AI PR reviewer action using Codium-ai/pr-agent - Configure stale issues and greetings automations - Configure PR labeler based on file paths - Add codeql security analysis workflow - Add unified repo-maintenance workflow for formatting, linting, docs, kg, and sboms - Create ast-based automated docs syncing tool - Create ast-based automated knowledge graph generation tool - Setup dependabot for pip, npm, and gh-actions - Separate GitHub Pages deployment into its own workflow - Configure robust testing CI Co-authored-by: NITISH-R-G <225521762+NITISH-R-G@users.noreply.github.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…lities - Setup community guidelines and templates - Configure AI PR reviewer action using coderabbitai/ai-pr-reviewer - Configure stale issues and greetings automations - Configure PR labeler based on file paths - Add codeql security analysis workflow - Add unified repo-maintenance workflow for formatting, linting, docs, kg, and sboms - Create ast-based automated docs syncing tool - Create ast-based automated knowledge graph generation tool - Setup dependabot for pip, npm, and gh-actions - Separate GitHub Pages deployment into its own workflow - Configure robust testing CI Co-authored-by: NITISH-R-G <225521762+NITISH-R-G@users.noreply.github.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
This PR drastically transforms the repository into an advanced, autonomous engineering system to minimize human intervention and maximize GitHub's free tier functionality.
CODEOWNERS,CODE_OF_CONDUCT.md, andCONTRIBUTING.md. Setupgreetings.yml,stale.yml, andlabeler.ymlto automatically manage contributors.coderabbitai/openai-pr-reviewerinai-review.yml.repo-maintenance.ymlto automatically format, lint, generate dependency SBOMs, build the codebase knowledge graph, and sync API documentation every night and on pushes.astmodule (docs_sync.pyandgenerate_knowledge_graph.py) to keep project structure self-documented indocs/api/. Fixed namespace collisions in documentation generation.dependabot.ymlfor ecosystem updates, and split the deployment of GitHub pages to its own dedicated workflow (pages.yml). Added robust python pytest workflow (ci.yml).PR created automatically by Jules for task 13502038526694898968 started by @NITISH-R-G
Summary by Sourcery
Automate repository maintenance, security scanning, CI, and community workflows, and generate synchronized API documentation and a code knowledge graph.
New Features:
Enhancements:
Build:
CI:
Deployment:
Documentation:
Tests:
Chores: