Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/workflows/check_dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Check Dependencies

on:
schedule:
- cron: '0 2 * * *'
workflow_dispatch: {}
Comment on lines +4 to +6
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Adjust schedule frequency and add human safeguards.

The workflow runs daily at 02:00 UTC. Depending on the repository size and number of dependencies, this could generate many PRs. Without safeguards (e.g., draft PRs, auto-merge restrictions, max PR limits), the workflow could overwhelm reviewers.

Consider:

  1. Increasing frequency to weekly or less often
  2. Restricting PR creation to draft status initially
  3. Adding a step to check if recent PRs already exist before creating new ones
   schedule:
-    - cron: '0 2 * * *'
+    - cron: '0 2 * * 0'  # Weekly instead of daily
🤖 Prompt for AI Agents
In .github/workflows/check_dependencies.yml around lines 4-6, the schedule runs
daily and lacks safeguards; change the cron to a weekly cadence (e.g., once a
week), modify the PR-creation step to open dependency PRs as draft by default,
and add a pre-check step that queries the GitHub API for existing open
dependency update PRs (or PRs created in the last N days) and exits early if
such PRs exist to enforce a max-one-open policy; also ensure any automatic merge
action is disabled or gated behind a label/review check.


jobs:
update-dependencies:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.VISION_AGENTS_GITHUB_TOKEN }}
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Install Cursor CLI
run: |
curl https://cursor.com/install -fsS | bash
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

⚠️ Replace unsafe script execution with secure installation method.

Piping curl output directly to bash is a security anti-pattern and vulnerable to MITM attacks. Additionally, there's no verification that the installation succeeded before proceeding.

Replace this with a secure installation method:

-          curl https://cursor.com/install -fsS | bash
-          echo "$HOME/.cursor/bin" >> $GITHUB_PATH
+          # Use a package manager or verify checksum instead of piping to bash
+          # For example, if available via package managers:
+          # sudo apt-get install cursor
+          # Or manually verify the binary before execution
+          curl -fsSL https://cursor.com/install -o /tmp/cursor-install.sh
+          # TODO: Add checksum verification here before executing
+          bash /tmp/cursor-install.sh
+          echo "$HOME/.cursor/bin" >> $GITHUB_PATH

Alternatively, check if Cursor provides a published package in standard package managers or a tarball with published checksums.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/check_dependencies.yml around line 33: the workflow uses an
unsafe pattern "curl ... | bash" to install Cursor; replace it with a secure
installation sequence that either (1) uses an official package from a system
package manager or the project's published installer package, or (2) downloads a
release tarball/installer to a temporary file, fetches and verifies its checksum
or GPG signature against the project's published value, then executes the
installer from disk; after installation, explicitly verify the installed
binary/version and fail the job if verification or installation fails so the
workflow does not continue on an untrusted or incomplete install.

echo "$HOME/.cursor/bin" >> $GITHUB_PATH

- name: Configure git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"

- name: Check and update dependencies with Cursor Agent
env:
CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
GH_TOKEN: ${{ secrets.VISION_AGENTS_GITHUB_TOKEN }}
run: |
cursor-agent -p "You are a dependency update bot. Your task is to check for outdated Python dependencies and create PRs to update them.

## Step 1: Discover pyproject.toml files
Find all pyproject.toml files in this repository, excluding .venv directories.

## Step 2: Check for outdated dependencies
For each pyproject.toml, extract dependencies from:
- [project].dependencies
- [project].optional-dependencies
- [dependency-groups]

Skip packages that are workspace packages (listed in [tool.uv.sources] with workspace = true or path references like vision-agents-*, etc.).

For each external package, query PyPI (https://pypi.org/pypi/{package}/json) to get the latest version.

Categorize updates into:
- PATCH/MINOR: e.g., 1.2.0 -> 1.2.5 or 1.2.0 -> 1.3.0
- MAJOR: e.g., 1.2.0 -> 2.0.0

## Step 3: Create PR for patch/minor updates
If there are patch/minor updates:
1. Create branch: deps/patch-minor-YYYYMMDD
2. Update pyproject.toml files with patch/minor version bumps only
3. Preserve exact formatting, extras, and markers
4. Respect override-dependencies in root pyproject.toml
5. Commit with message: 'chore: update dependencies (patch/minor)'
6. Push and create PR with:
- Title: 'chore: update dependencies (patch/minor)'
- Body: Table of updated packages with old -> new versions
- Labels: dependencies, automated

## Step 4: Create separate PR for major updates
If there are major updates:
1. Reset to main branch
2. Create branch: deps/major-YYYYMMDD
3. Update pyproject.toml files with major version bumps only
4. Preserve exact formatting, extras, and markers
5. Commit with message: 'chore: update dependencies (major) - BREAKING'
6. Push and create PR with:
- Title: 'chore: update dependencies (major) ⚠️ BREAKING'
- Body: Table of updated packages with old -> new versions, note that these are major updates requiring manual review
- Labels: dependencies, automated, breaking

## Step 5: Summary
Print a summary of what was done:
- Number of patch/minor updates (and PR link if created)
- Number of major updates (and PR link if created)
- Any packages that were skipped and why

If no updates needed, print 'All dependencies are up to date'." --model gpt-4o
Copy link

Choose a reason for hiding this comment

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

Bug: Missing lockfile update after dependency version changes

The workflow prompts cursor-agent to update pyproject.toml files with new dependency versions but never instructs it to run uv lock to update the uv.lock lockfile. This project uses uv with UV_FROZEN: "1" in tests and --frozen flags, requiring the lockfile to be in sync with pyproject.toml. PRs created by this workflow will have mismatched pyproject.toml and uv.lock files, causing CI test failures when the lockfile check runs against the updated dependencies.

Fix in Cursor Fix in Web

Comment on lines +42 to +95
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

⚠️ Reliance on AI agent for critical PR automation is unreliable and risky.

The workflow offloads all dependency checking, version categorization, and PR creation logic to a natural language prompt sent to cursor-agent. This approach has several systemic risks:

  1. Unverifiable logic: The AI agent's interpretation of the prompt cannot be audited before execution. If it misinterprets instructions (e.g., incorrectly categorizes versions, skips packages, or modifies unrelated dependencies), the damage is already done post-merge.
  2. No error recovery: There's no validation that PRs were created correctly, commits match expectations, or files were modified as intended.
  3. Dependency on external service: If Cursor's API is down, rate-limited, or changes behavior, the workflow silently fails or produces unexpected results.
  4. PR spam risk: Without explicit safeguards, the workflow could create many PRs in a single run, overwhelming the review queue.
  5. Timeout hazard: No timeout is specified; a hanging cursor-agent command could consume runner resources indefinitely.

Recommendation: Replace this with a deterministic, auditable approach using established dependency update tools:

-      - name: Check and update dependencies with Cursor Agent
+      - name: Check and update dependencies
         env:
-          CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
           GH_TOKEN: ${{ secrets.VISION_AGENTS_GITHUB_TOKEN }}
-        run: |
-          cursor-agent -p "..." --model gpt-4o
+        uses: dependabot/fetch-metadata@v2
+        # OR use Renovate for more advanced categorization
+        # OR implement a custom Python script with explicit error handling

If cursor-agent is required, at minimum add:

  • Explicit timeout (e.g., timeout 600)
  • Exit code validation
  • Output validation (check created PRs exist)
  • Rate limiting (skip if PRs already exist from recent runs)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/check_dependencies.yml lines 42-95: the workflow currently
delegates all dependency discovery, version categorization, and PR creation to
cursor-agent via a long natural-language prompt (unreliable and unauditable);
replace this with a deterministic dependency-updater (e.g., dependabot,
poetry-lock-update, pip-upgrade-action or a custom script) that explicitly finds
pyproject.toml files, queries PyPI, classifies semver changes, and creates PRs,
or — if cursor-agent must remain — wrap the call with strict safeguards: enforce
a hard timeout (e.g., timeout 600s), check the cursor-agent exit code and fail
the job on nonzero, validate output by confirming created PRs via the GitHub API
before pushing commits/labels, rate-limit and skip if recent automated PRs
already exist, and add explicit logging and retry/error-handling to ensure
auditable, recoverable behavior.