Skip to content

chore(renovate): P4a — durable lock-regen (fleet pip-compile manager + auto-lock backstop) - #2406

Merged
stranske merged 1 commit into
mainfrom
chore/p4a-renovate-lock-regen
Jun 15, 2026
Merged

chore(renovate): P4a — durable lock-regen (fleet pip-compile manager + auto-lock backstop)#2406
stranske merged 1 commit into
mainfrom
chore/p4a-renovate-lock-regen

Conversation

@stranske

@stranske stranske commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Priority 1 — lock-regen gap (durable / systemic fix)

Builds on #2404, which already fixed the one-time symptoms (regenerated the stale lock after Renovate #2389, and reconciled the conflicting pytest pin to 9.1.0 so uv pip compile is satisfiable again). This PR adds the systemic fix so the gap cannot recur, and wires the consumer story that Dependabot's native lock update used to cover.

Why #2404 alone isn't enough

#2404 noted "Renovate's pip-compile manager is not enabled in the fleet preset, so it does not regenerate this uv-pip-compile lock." That's the root gap — without it, every future Renovate source bump leaves requirements.lock stale (and consumers, which have no auto-lock workflow, never regenerate at all).

Changes

  • renovate-presets/fleet.json — enable the pip-compile manager against requirements.lock. The hosted Renovate app re-runs the uv pip compile command recorded in the lock header and regenerates the lock in the same PR, fleet-wide (Workflows + every consumer extends this preset). This is the answer to the consumer investigation: consumers relied on Dependabot's native lock update; this preset restores it. lockFileMaintenance is on by default in the manager — no postUpdateOptions needed.
  • maint-dependabot-auto-lock.yml — extend to renovate[bot] + renovate/** as a Workflows-local backstop, and rewrite it to re-run the same header command verbatim instead of recomputing args. The old dynamic args added the empty app extra + tools/requirements-llm.txt, diverging from the header → would have flip-flopped commits against Renovate's regen (the "fight automerge" failure mode). Re-running the header guarantees byte-identical output, so the backstop no-ops when Renovate already regenerated and only acts if that ever fails.
  • requirements.txt — remove the pytest pin entirely. fix(deps): regenerate stale requirements.lock + reconcile pytest pin #2404 aligned it to 9.1.0, but sync_dev_dependencies.py syncs autofix-versions.envpyproject + requirements.lock and not requirements.txt, so a pin here re-drifts on the next pytest bump and re-breaks the lock — defeating the pip-compile manager. Removing it keeps the dev-tool pin in a single owner; the lock still carries pytest 9.1.0 via the dev extra (lock diff is the single now-stale # -r requirements.txt annotation).

Verification

  • uv pip compile (main's header command) succeeds; lock diff vs main is one annotation line.
  • tests/test_dependency_version_alignment.py, tests/scripts/test_sync_{dev_dependencies,tool_versions}.py30 passed.
  • actionlint clean on the rewritten workflow.

Part of P4 (finish retiring Dependabot). Follows #2386/#2394/#2401/#2404.

Summary by CodeRabbit

  • Chores
    • Improved CI automation for lock-file regeneration, including a safer backstop that reuses the exact compile command recorded in the existing lock file header.
    • Updated the Renovate fleet configuration to explicitly enable pip-compile/uv pip compile-based regeneration scoped to requirements.lock.
    • Refined dependency version management by removing the pinned pytest line from requirements.txt and clarifying that dev/test versions are managed via existing synchronization tooling and config.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR introduces Renovate's pip-compile manager in fleet.json as the primary in-PR lock regeneration mechanism for requirements.lock. The workflow backstop is rewritten to extract and replay the uv pip compile command recorded in the lock header instead of reconstructing arguments from pyproject.toml. Trigger paths and job conditions are extended to cover renovate[bot], and the pytest pin is removed from requirements.txt to eliminate lock drift.

Changes

Renovate pip-compile Lock Regeneration + Workflow Backstop

Layer / File(s) Summary
Renovate fleet pip-compile manager config
renovate-presets/fleet.json
Adds a pip-compile manager block with managerFilePatterns targeting requirements.lock, and updates the preset description to document pip-compile/uv pip compile lock regeneration behavior, making Renovate the primary driver of in-PR lock regeneration.
Remove pytest pin from requirements.txt
requirements.txt
Removes the pytest pin and adds comments directing dev/test pins to autofix-versions.env/pyproject.toml, eliminating the source of lock drift.
Workflow trigger, condition, and regeneration logic rewrite
.github/workflows/maint-dependabot-auto-lock.yml
Updates the header comment, adds renovate/** to path filters, broadens the job condition to include renovate[bot], replaces the pyproject.toml-argument reconstruction with sed-based header-command extraction and git diff detection, and updates the commit message.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • stranske/Workflows#2404: Both PRs modify pytest pinning in requirements.txt and address lock regeneration behavior; this PR removes the pytest pin entirely while the related PR updates it to 9.1.0.
  • stranske/Workflows#2386: Introduces the Renovate fleet preset baseline in renovate-presets/fleet.json that this PR extends with the pip-compile manager configuration.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: implementing durable lock regeneration via Renovate fleet pip-compile manager and auto-lock backstop workflow. It directly matches the PR's core objective of fixing the lock-file regeneration gap.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/p4a-renovate-lock-regen

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

@stranske
stranske temporarily deployed to agent-high-privilege June 15, 2026 05:51 — with GitHub Actions Inactive
@agents-workflows-bot

Copy link
Copy Markdown
Contributor

Workflow source needed

PR #2406 needs either a linked GitHub issue or one valid non-issue Workflow Source before PR metadata automation can manage it safely.

Please do one of:

  • Add <!-- meta:issue:123 --> or a normal Closes #123 / Related to #123 line.
  • Check one Workflow Source option in the PR body.
  • Add a hidden marker such as <!-- workflow-source:local_request -->, <!-- workflow-source:manual_remote -->, <!-- workflow-source:review_followup -->, <!-- workflow-source:sync_campaign -->, or <!-- workflow-source:dependabot -->.
  • Add a workflow source label such as workflow:source-direct-pr, workflow:source-local-request, workflow:source-review-followup, workflow:source-sync, or workflow:no-automation.

Once a valid source is present, this warning will not be reposted.

@agents-workflows-bot

agents-workflows-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Automated Status Summary

Head SHA: a83d900
Latest Runs: ⏳ pending — Gate
Required contexts: Gate / gate, Health 45 Agents Guard / guard
Required: core tests (3.12): ⏳ pending, core tests (3.13): ⏳ pending, docker smoke: ⏳ pending, gate: ⏳ pending

Workflow / Job Result Logs
(no jobs reported) ⏳ pending

Coverage Overview

  • Coverage history entries: 1

Coverage Trend

Metric Value
Current 70.26%
Baseline 85.00%
Delta -14.74%
Minimum 70.00%
Status ✅ Pass

Top Coverage Hotspots (lowest coverage)

File Coverage Missing
scripts/check_api_wrapper_guard.py 0.0% 123
scripts/cleanup_labels.py 0.0% 127
scripts/issue_dedup_smoke.py 0.0% 4
scripts/list_registered_consumer_repos.py 0.0% 33
scripts/repo_review_backlog_scan.py 0.0% 203
scripts/repo_review_queue_builder.py 0.0% 105
scripts/repo_review_round1_runner.py 0.0% 225
scripts/repo_review_round1_schema.py 0.0% 194
scripts/runner_lib/__main__.py 0.0% 3
scripts/update_langchain_versions.py 0.0% 34
scripts/validate_dependency_test_setup.py 0.0% 112
scripts/validate_template_completeness.py 0.0% 88
scripts/validate_template_sync.py 0.0% 77
scripts/validate_workflow_yaml.py 0.0% 98
scripts/repo_review_round2_schema.py 8.8% 185

Low Coverage Files (<50.0%)

File Coverage Missing
scripts/check_api_wrapper_guard.py 0.0% 123
scripts/cleanup_labels.py 0.0% 127
scripts/issue_dedup_smoke.py 0.0% 4
scripts/list_registered_consumer_repos.py 0.0% 33
scripts/repo_review_backlog_scan.py 0.0% 203
scripts/repo_review_queue_builder.py 0.0% 105
scripts/repo_review_round1_runner.py 0.0% 225
scripts/repo_review_round1_schema.py 0.0% 194
scripts/runner_lib/__main__.py 0.0% 3
scripts/update_langchain_versions.py 0.0% 34
scripts/validate_dependency_test_setup.py 0.0% 112
scripts/validate_template_completeness.py 0.0% 88
scripts/validate_template_sync.py 0.0% 77
scripts/validate_workflow_yaml.py 0.0% 98
scripts/repo_review_round2_schema.py 8.8% 185

Updated automatically; will refresh on subsequent CI/Docker completions.


Keepalive checklist

Scope

No scope information available

Tasks

  • No tasks defined

Acceptance criteria

  • No acceptance criteria defined

@stranske
stranske force-pushed the chore/p4a-renovate-lock-regen branch from dce23aa to f717942 Compare June 15, 2026 05:55

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dce23aaa45

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- 'tools/requirements-llm.txt'
branches:
- 'dependabot/**'
- 'renovate/**'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Filter Renovate PRs with head_ref instead

For pull_request, the branches filter matches the PR target/base branch, not the source branch (GitHub docs describe this as PRs that target matching branches). Normal Renovate PRs come from renovate/... into main, so this new pattern prevents the workflow from being queued before the job-level actor check can run, and the advertised Renovate backstop never runs when Renovate fails to regenerate the lock. Use a base branch filter such as main (or remove it) and gate source branches with github.head_ref in the job if.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/maint-dependabot-auto-lock.yml:
- Around line 67-75: The `args` variable extracted from the `requirements.lock`
file header via sed is directly expanded unquoted in the `uv pip compile
${args}` command invocation, creating a shell injection vulnerability. To fix
this, validate that the extracted `args` contains only safe, whitelisted tokens
(such as package names, version operators like ==, >=, etc., and no shell
metacharacters), and then use proper quoting or bash array semantics when
passing the arguments to the uv command to prevent unintended command execution.
Consider splitting the args into an array and using the safe argument expansion
pattern to eliminate the injection vector.
- Line 35: The `if` condition uses `github.actor` which is exploitable through
workflow reruns and does not securely verify the actual pull request author.
Replace the `github.actor` checks in the condition with
`github.event.pull_request.user.login` to gate the workflow on the actual PR
author identity instead, following GitHub Actions security best practices for
pull request events.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e0adf792-d9b0-4a21-a928-d22da150bf69

📥 Commits

Reviewing files that changed from the base of the PR and between 494a262 and dce23aa.

⛔ Files ignored due to path filters (2)
  • requirements.lock is excluded by !**/*.lock, !**/*.lock
  • uv.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/maint-dependabot-auto-lock.yml
  • renovate-presets/fleet.json
  • requirements.txt
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • stranske/Template (auto-detected)

name: Regenerate requirements.lock
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find and inspect the workflow file
find . -name "maint-dependabot-auto-lock.yml" -type f | head -5

Repository: stranske/Workflows

Length of output: 113


🏁 Script executed:

#!/bin/bash
# Read the entire workflow file with line numbers
cat -n .github/workflows/maint-dependabot-auto-lock.yml

Repository: stranske/Workflows

Length of output: 4483


🌐 Web query:

GitHub Actions github.actor context spoofable rerun security

💡 Result:

The github.actor context in GitHub Actions is considered spoofable and insecure for gatekeeping privileged operations [1][2][3]. This is because it refers to the user who triggered the specific event that initiated the current workflow run [4], not necessarily the original creator of a pull request or the author of the code being executed [5][3]. Attackers can exploit this behavior, particularly in workflows using events like pull_request_target, by performing actions—such as commenting on a pull request or triggering a re-run—that cause the workflow to re-trigger [4]. If an attacker controls an event that triggers a re-run, they can manipulate the workflow into executing with a github.actor value that appears to be a trusted account (e.g., 'dependabot[bot]') [4][6]. Relying on this value to grant permissions or execute code can lead to a Confused Deputy attack, where a privileged process is tricked into performing malicious actions [5]. To securely validate actors, you should avoid relying on github.actor for security-critical decisions [2][3]. Instead, use immutable, event-specific contexts that represent the true initiator or author of the event [1][7][6]: 1. For pull request events, use github.event.pull_request.user.login to verify the original PR author [1][7]. 2. For comment-based triggers, use github.event.comment.user.login [1]. 3. For general security-critical validation, consider comparing against the actor's unique numeric ID (github.actor_id or event-specific IDs) rather than their username, which can be impersonated or registered by attackers [1][8]. 4. Always implement additional defense-in-depth measures for workflows that handle secrets or privileged operations, such as explicitly checking that the pull request does not originate from a fork (github.event.pull_request.head.repo.fork == false) [7][9].

Citations:


🏁 Script executed:

#!/bin/bash
# Search for any comments, issues, or discussions about github.actor in workflows
rg "github\.actor|github\.event\.pull_request\.user" --type yaml -C 2

Repository: stranske/Workflows

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Check if other workflows in this repo use the safer pattern
find .github/workflows -name "*.yml" -o -name "*.yaml" | xargs grep -l "if:" | head -5 | xargs cat | grep -A 2 "github.event.pull_request"

Repository: stranske/Workflows

Length of output: 251


Use PR author identity for bot gating, not github.actor.

Line 35 uses github.actor, which is exploitable through workflow reruns. For a pull request event, gate on github.event.pull_request.user.login instead, following GitHub Actions security best practices.

Suggested fix
-    if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
+    if: contains(fromJSON('["dependabot[bot]","renovate[bot]"]'), github.event.pull_request.user.login)
📝 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.

Suggested change
if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
if: contains(fromJSON('["dependabot[bot]","renovate[bot]"]'), github.event.pull_request.user.login)
🤖 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/maint-dependabot-auto-lock.yml at line 35, The `if`
condition uses `github.actor` which is exploitable through workflow reruns and
does not securely verify the actual pull request author. Replace the
`github.actor` checks in the condition with
`github.event.pull_request.user.login` to gate the workflow on the actual PR
author identity instead, following GitHub Actions security best practices for
pull request events.

Source: Coding guidelines

Comment on lines +67 to +75
args=$(sed -n 's/^#[[:space:]]*uv pip compile[[:space:]]\{1,\}\(.*\)$/\1/p' requirements.lock | head -n1)
if [ -z "${args}" ]; then
echo "::error::Could not parse a 'uv pip compile' command from the requirements.lock header."
exit 1
fi
echo "Recorded command: uv pip compile ${args}"

- name: Check if lock file needs update
id: check
run: |
out=requirements.check
log=compile.log
compile_args="${{ steps.compile_args.outputs.compile_args }}"
uv pip compile ${compile_args} "$out" 2>&1 | tee "$log" || {
# shellcheck disable=SC2086
uv pip compile ${args} 2>&1 | tee compile.log || {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm the file exists and check the exact code at lines 67-75
echo "=== Checking file existence and content ==="
if [ -f ".github/workflows/maint-dependabot-auto-lock.yml" ]; then
  echo "File found"
  echo "Lines 67-75:"
  sed -n '67,75p' .github/workflows/maint-dependabot-auto-lock.yml
else
  echo "File not found"
fi

# Check if requirements.lock exists
echo -e "\n=== Checking for requirements.lock ==="
find . -name "requirements.lock" -type f | head -20

Repository: stranske/Workflows

Length of output: 638


🏁 Script executed:

#!/bin/bash
# Examine actual requirements.lock files to understand the header format
echo "=== Sample requirements.lock headers ==="
find . -name "requirements.lock" -type f | while read -r file; do
  echo "--- $file ---"
  head -n 3 "$file"
  echo ""
done | head -50

Repository: stranske/Workflows

Length of output: 367


🏁 Script executed:

#!/bin/bash
# Check the full context around lines 60-80 to understand the workflow better
echo "=== Full context of the workflow (lines 60-85) ==="
sed -n '60,85p' .github/workflows/maint-dependabot-auto-lock.yml

Repository: stranske/Workflows

Length of output: 1372


🏁 Script executed:

#!/bin/bash
# Check Template's requirements.lock header format to understand what gets stored
echo "=== Template requirements.lock header ==="
if [ -f "requirements.lock" ]; then
  head -n 5 requirements.lock
else
  echo "No requirements.lock found"
fi

Repository: stranske/Template

Length of output: 307


Harden header-command replay against shell injection.

Lines 67-75 parse command text from requirements.lock and execute it via unquoted expansion. Although the lock file is generated by uv itself and commits are subject to review, this is still exploitable if a malicious requirements.lock reaches main. Validate safe tokens and use argv-array semantics to eliminate the vector.

Suggested fix
-          args=$(sed -n 's/^#[[:space:]]*uv pip compile[[:space:]]\{1,\}\(.*\)$/\1/p' requirements.lock | head -n1)
-          if [ -z "${args}" ]; then
+          args=$(sed -n 's/^#[[:space:]]*uv pip compile[[:space:]]\{1,\}\(.*\)$/\1/p' requirements.lock | head -n1)
+          if [ -z "${args}" ]; then
             echo "::error::Could not parse a 'uv pip compile' command from the requirements.lock header."
             exit 1
           fi
-          echo "Recorded command: uv pip compile ${args}"
+          if printf '%s' "${args}" | grep -Eq '[;&|`$()<>]'; then
+            echo "::error::Unsafe token detected in lock header command."
+            exit 1
+          fi
+          read -r -a uv_args <<< "${args}"
+          echo "Recorded command: uv pip compile ${args}"
 
           # shellcheck disable=SC2086
-          uv pip compile ${args} 2>&1 | tee compile.log || {
+          uv pip compile "${uv_args[@]}" 2>&1 | tee compile.log || {
             echo "❌ Compilation failed:"
             cat compile.log
             exit 1
           }

As per coding guidelines, ".github/workflows/**: Flag template-injection, unpinned third-party actions, and spoofable bot-actor checks — this workflow YAML is synced to 9 consumer repos, so one bug replicates fleet-wide."

🤖 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/maint-dependabot-auto-lock.yml around lines 67 - 75, The
`args` variable extracted from the `requirements.lock` file header via sed is
directly expanded unquoted in the `uv pip compile ${args}` command invocation,
creating a shell injection vulnerability. To fix this, validate that the
extracted `args` contains only safe, whitelisted tokens (such as package names,
version operators like ==, >=, etc., and no shell metacharacters), and then use
proper quoting or bash array semantics when passing the arguments to the uv
command to prevent unintended command execution. Consider splitting the args
into an array and using the safe argument expansion pattern to eliminate the
injection vector.

Source: Coding guidelines

…+ auto-lock backstop)

Builds on #2404, which fixed the one-time symptoms (regenerated the stale lock
and reconciled the pytest pin to 9.1.0). This PR adds the SYSTEMIC fix so the
gap cannot recur, and wires the consumer story Dependabot's native lock update
used to cover.

- renovate-presets/fleet.json: enable the pip-compile manager against
  requirements.lock. The hosted Renovate app re-runs the uv command recorded in
  the lock header and regenerates the lock IN the same PR — fleet-wide, for
  Workflows and every consumer (all extend this preset). #2404 noted the manager
  was not enabled; this enables it. lockFileMaintenance is on by default in the
  manager (no postUpdateOptions needed).
- maint-dependabot-auto-lock.yml: extend to renovate[bot] + renovate/** as a
  Workflows-local backstop, and rewrite it to re-run the SAME header command
  verbatim instead of recomputing args. The old dynamic args added the empty
  `app` extra + tools/requirements-llm.txt, which diverged from the header and
  would have flip-flopped commits against Renovate's regen.
- requirements.txt: remove the pytest pin entirely (a dev/test tool). #2404
  aligned it to 9.1.0, but sync_dev_dependencies.py syncs env -> pyproject +
  lock and NOT requirements.txt, so a pin here re-drifts on the next pytest bump
  and re-breaks the lock — defeating the pip-compile manager. Removing it keeps
  the dev-tool pin in a single owner; the lock still carries pytest 9.1.0 via
  the dev extra (lock diff is the one stale `# -r requirements.txt` annotation).

Verified: uv recompile succeeds; dependency-alignment + dev-version sync tests
pass (30); actionlint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stranske
stranske force-pushed the chore/p4a-renovate-lock-regen branch from f717942 to c841cf0 Compare June 15, 2026 05:59
@stranske
stranske temporarily deployed to agent-high-privilege June 15, 2026 06:00 — with GitHub Actions Inactive
@stranske stranske changed the title chore(renovate): P4a — fix lock-regen gap (fleet pip-compile manager + auto-lock backstop) chore(renovate): P4a — durable lock-regen (fleet pip-compile manager + auto-lock backstop) Jun 15, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/maint-dependabot-auto-lock.yml:
- Around line 19-21: The `branches` filter in the `pull_request` trigger (lines
19-21) incorrectly filters the base branch rather than the source branch, which
prevents proper detection of dependabot and renovate PRs. Remove the entire
`branches` filter from the pull_request configuration, and instead add an `if`
condition at the job level that uses `github.head_ref` to match against the
patterns 'dependabot/**' and 'renovate/**'. This will properly detect when the
source branch of the PR originates from dependabot or renovate, which is the
intended behavior for automatically locking these bot-generated pull requests.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8cbf9c6e-fc4f-4eb6-8561-b2d02229b50e

📥 Commits

Reviewing files that changed from the base of the PR and between dce23aa and f717942.

⛔ Files ignored due to path filters (1)
  • requirements.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/maint-dependabot-auto-lock.yml
  • renovate-presets/fleet.json
  • requirements.txt
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • stranske/Template (auto-detected)

Comment on lines 19 to +21
branches:
- 'dependabot/**'
- 'renovate/**'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/maint-dependabot-auto-lock.yml | head -50

Repository: stranske/Workflows

Length of output: 1926


🌐 Web query:

GitHub Actions pull_request branches filter base branch or head branch documentation

💡 Result:

In GitHub Actions, the branches and branches-ignore filters used within the on.pull_request (or on.pull_request_target) configuration exclusively target the pull request's base branch (the branch you are merging into) [1][2][3]. There is no native syntax in the on configuration to filter by the head branch (the source branch or the branch being merged from) [4]. To filter by the head branch, you must use a conditional if expression at the job or step level [1][5][4]. 1. Filtering by Base Branch (on configuration): Use the branches filter under the pull_request event. This will cause the workflow to run only when a pull request targets a branch matching the specified pattern [1][2]. on: pull_request: branches: - main - 'releases/' 2. Filtering by Head Branch (if condition): To filter by the head branch, use the github.head_ref context within a job's if condition [1][6]. This allows you to restrict specific jobs to only run when the pull request originates from a particular source branch [1][4]. jobs: my_job: if: github.head_ref == 'feature-branch' runs-on: ubuntu-latest steps: - run: echo "This job only runs if the head branch is 'feature-branch'" You can also combine these techniques to filter by both base and head branches simultaneously [5][4]. For example: on: pull_request: branches: - main jobs: my_job: if: startsWith(github.head_ref, 'feature/') runs-on: ubuntu-latest steps: - run: echo "Runs for PRs from 'feature/*' into 'main'"

Citations:


🏁 Script executed:

cat -n .github/workflows/maint-dependabot-auto-lock.yml | sed -n '50,80p'

Repository: stranske/Workflows

Length of output: 1624


🏁 Script executed:

head -n 3 requirements.lock

Repository: stranske/Template

Length of output: 236


pull_request.branches filters the base branch, not the source branch—this prevents the intended bot-PR detection.

The branches filter at lines 19–21 applies to the PR's target branch (e.g., main), not the source branch (dependabot/**, renovate/**). This means the filter will not reliably trigger on bot PRs originating from those branches. Additionally, the job-level actor check (github.actor == 'dependabot[bot]') is spoofable.

Use github.head_ref in the job if condition to detect the source branch, and remove the branches filter:

Suggested fix
 on:
   pull_request:
     paths:
       - 'pyproject.toml'
       - 'requirements.txt'
       - 'tools/requirements-llm.txt'
-    branches:
-      - 'dependabot/**'
-      - 'renovate/**'
-    if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
+    if: >
+      startsWith(github.head_ref, 'dependabot/') || startsWith(github.head_ref, 'renovate/')
🤖 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/maint-dependabot-auto-lock.yml around lines 19 - 21, The
`branches` filter in the `pull_request` trigger (lines 19-21) incorrectly
filters the base branch rather than the source branch, which prevents proper
detection of dependabot and renovate PRs. Remove the entire `branches` filter
from the pull_request configuration, and instead add an `if` condition at the
job level that uses `github.head_ref` to match against the patterns
'dependabot/**' and 'renovate/**'. This will properly detect when the source
branch of the PR originates from dependabot or renovate, which is the intended
behavior for automatically locking these bot-generated pull requests.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (3)
.github/workflows/maint-dependabot-auto-lock.yml (3)

35-35: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Use PR author identity for bot gating, not github.actor.

github.actor is exploitable through workflow reruns. An attacker can re-run the workflow, causing github.actor to reflect the rerun triggerer rather than the original PR author. For pull request events, gate on github.event.pull_request.user.login instead, following GitHub Actions security best practices.

🔒 Suggested fix
-    if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
+    if: contains(fromJSON('["dependabot[bot]","renovate[bot]"]'), github.event.pull_request.user.login)

As per coding guidelines, ".github/workflows/**: Flag template-injection, unpinned third-party actions, and spoofable bot-actor checks — this workflow YAML is synced to 9 consumer repos, so one bug replicates fleet-wide."

🤖 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/maint-dependabot-auto-lock.yml at line 35, The condition
uses `github.actor` which is exploitable during workflow reruns, as it reflects
the rerun triggerer rather than the original PR author. Replace the
`github.actor` checks in the if condition with
`github.event.pull_request.user.login` to properly gate on the actual pull
request author's identity, ensuring the workflow only runs when the PR was
originally created by dependabot or renovate, not when an attacker reruns the
workflow.

Source: Coding guidelines


19-21: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

pull_request.branches filters the base branch, not the source branch—this prevents the intended bot-PR detection.

The branches filter applies to the PR's target branch (e.g., main), not the source branch (dependabot/**, renovate/**). Bot PRs originate from branches matching those patterns, but target main or similar, so this filter will not trigger as intended.

Remove the branches filter and use github.head_ref in the job if condition to detect the source branch pattern.

🔧 Suggested fix

Remove the branches filter:

 on:
   pull_request:
     paths:
       - 'pyproject.toml'
       - 'requirements.txt'
       - 'tools/requirements-llm.txt'
-    branches:
-      - 'dependabot/**'
-      - 'renovate/**'

Update the job condition at line 35 to check the head branch:

-    if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
+    if: startsWith(github.head_ref, 'dependabot/') || startsWith(github.head_ref, 'renovate/')
🤖 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/maint-dependabot-auto-lock.yml around lines 19 - 21, The
pull_request.branches filter checks the target branch (main), not the source
branch where bot PRs originate (dependabot/**, renovate/**), so it will not
trigger the workflow as intended. Remove the entire branches filter block
containing dependabot/** and renovate/**, and instead update the job if
condition at line 35 to use github.head_ref to check whether the source branch
matches the pattern for dependabot or renovate bot PRs.

Source: Coding guidelines


67-75: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Harden header-command replay against shell injection.

Lines 67-75 extract command arguments from requirements.lock via sed and execute them with unquoted expansion (uv pip compile ${args}). Although the lock is generated by uv and commits are reviewed, this creates a shell injection vector if a malicious requirements.lock reaches main—particularly critical given this workflow syncs to 9 consumer repos.

Validate that extracted args contain only safe tokens (flags, paths, version operators) and use bash array semantics to eliminate the injection risk.

🛡️ Suggested fix
           args=$(sed -n 's/^#[[:space:]]*uv pip compile[[:space:]]\{1,\}\(.*\)$/\1/p' requirements.lock | head -n1)
           if [ -z "${args}" ]; then
             echo "::error::Could not parse a 'uv pip compile' command from the requirements.lock header."
             exit 1
           fi
+          # Validate that args contains only safe tokens (no shell metacharacters)
+          if printf '%s' "${args}" | grep -Eq '[;&|`$()<>]'; then
+            echo "::error::Unsafe token detected in lock header command."
+            exit 1
+          fi
+          # Split into array for safe expansion
+          read -r -a uv_args <<< "${args}"
           echo "Recorded command: uv pip compile ${args}"
 
           # shellcheck disable=SC2086
-          uv pip compile ${args} 2>&1 | tee compile.log || {
+          uv pip compile "${uv_args[@]}" 2>&1 | tee compile.log || {
             echo "❌ Compilation failed:"
             cat compile.log
             exit 1
           }

As per coding guidelines, ".github/workflows/**: Flag template-injection, unpinned third-party actions, and spoofable bot-actor checks — this workflow YAML is synced to 9 consumer repos, so one bug replicates fleet-wide."

🤖 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/maint-dependabot-auto-lock.yml around lines 67 - 75, The
shell variable args extracted from requirements.lock via sed is used with
unquoted expansion in the uv pip compile command, creating a shell injection
vulnerability if malicious content reaches the file. Add validation after the
sed extraction to ensure args contains only safe tokens such as flags (dashes),
paths (alphanumeric, dots, slashes), and version operators (equals,
greater-than, less-than, exclamation, tilde), and exit with an error if
validation fails. Then convert the args into a bash array and pass it using
array expansion syntax (args_array[@]) instead of the unquoted variable
expansion to safely prevent shell interpretation of any special characters.

Source: Coding guidelines

🤖 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.

Duplicate comments:
In @.github/workflows/maint-dependabot-auto-lock.yml:
- Line 35: The condition uses `github.actor` which is exploitable during
workflow reruns, as it reflects the rerun triggerer rather than the original PR
author. Replace the `github.actor` checks in the if condition with
`github.event.pull_request.user.login` to properly gate on the actual pull
request author's identity, ensuring the workflow only runs when the PR was
originally created by dependabot or renovate, not when an attacker reruns the
workflow.
- Around line 19-21: The pull_request.branches filter checks the target branch
(main), not the source branch where bot PRs originate (dependabot/**,
renovate/**), so it will not trigger the workflow as intended. Remove the entire
branches filter block containing dependabot/** and renovate/**, and instead
update the job if condition at line 35 to use github.head_ref to check whether
the source branch matches the pattern for dependabot or renovate bot PRs.
- Around line 67-75: The shell variable args extracted from requirements.lock
via sed is used with unquoted expansion in the uv pip compile command, creating
a shell injection vulnerability if malicious content reaches the file. Add
validation after the sed extraction to ensure args contains only safe tokens
such as flags (dashes), paths (alphanumeric, dots, slashes), and version
operators (equals, greater-than, less-than, exclamation, tilde), and exit with
an error if validation fails. Then convert the args into a bash array and pass
it using array expansion syntax (args_array[@]) instead of the unquoted variable
expansion to safely prevent shell interpretation of any special characters.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c918b8e8-f52a-4c84-a730-a11bbd9d11aa

📥 Commits

Reviewing files that changed from the base of the PR and between f717942 and c841cf0.

⛔ Files ignored due to path filters (1)
  • requirements.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/maint-dependabot-auto-lock.yml
  • renovate-presets/fleet.json
  • requirements.txt
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • stranske/Template (auto-detected)

@stranske
stranske merged commit 3ea58ad into main Jun 15, 2026
59 checks passed
@stranske
stranske deleted the chore/p4a-renovate-lock-regen branch June 15, 2026 06:12
stranske added a commit to stranske/Manager-Database that referenced this pull request Jun 15, 2026
…1170)

Renovate's pip-compile manager (enabled fleet-wide in the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option --extra must have equal sign" warning and SILENTLY SKIPPED the lock
— meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (verified: header-only diff). Confirmed via
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile now
extracts the lock (depCount 195) with no error.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Inv-Man-Intake that referenced this pull request Jun 15, 2026
)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Pension-Data that referenced this pull request Jun 15, 2026
)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Portable-Alpha-Extension-Model that referenced this pull request Jun 15, 2026
…1965)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/trip-planner that referenced this pull request Jun 15, 2026
…1391)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/learning-management-system that referenced this pull request Jun 15, 2026
)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Collab-Admin that referenced this pull request Jun 15, 2026
)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Trend_Model_Project that referenced this pull request Jun 15, 2026
…5565)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Template that referenced this pull request Jun 15, 2026
)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit to stranske/Travel-Plan-Permission that referenced this pull request Jun 15, 2026
…1210)

Renovate's pip-compile manager (enabled fleet-wide via the shared preset,
stranske/Workflows#2406) parses the lock header to reconstruct the uv
command and requires every option in equals form (--extra=, --output-file=).
This lock's header used space form, so Renovate raised a non-fatal
"Option ... must have equal sign" warning and SILENTLY SKIPPED the lock —
meaning it was never regenerated on dependency bumps.

This rewrites only the header line to equals form; the resolved pins are
byte-identical (header-only diff). Verified with
`npx renovate@43 --platform=local --dry-run=extract`: pip-compile extracts
the lock with no error after the change.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit that referenced this pull request Jun 15, 2026
…tenance (#2413)

Renovate's pip-compile manager (enabled on requirements.lock via the canary
renovate.json #2411 + fleet preset #2406) already owns periodic lock
regeneration: supportsLockFileMaintenance=true and its defaultConfig enables
lockFileMaintenance by default (branchTopic `pip-compile-refresh`), recompiling
the lock from scratch on a schedule. That makes maint-51-dependency-refresh.yml's
scheduled `uv pip compile --upgrade` a duplicate refresher (and it had failed
every run since ~March until #2404). Retire it.

Verified the feared `--upgrade`-in-header risk does NOT exist:
- uv omits `--upgrade` from the recorded lock header (empirically: compiles with
  and without `--upgrade` produce byte-identical headers).
- Even if it appeared, Renovate's pip-compile header parser (common.ts
  throwForUnknownOption) would throw `Option --upgrade not supported (yet)` and
  skip the file; it never re-runs a mass `--upgrade` (per-dep bumps are scoped
  via `--upgrade-package` in artifacts.ts).

maint-51's other steps remain covered: sync_test_dependencies.py --verify runs in
reusable-10-ci-python on every PR; dev-tool pin alignment is enforced on schedule
by maint-auto-update-pypi-versions + maint-sync-env-from-pyproject (--apply).

- delete .github/workflows/maint-51-dependency-refresh.yml
- drop its EXPECTED_NAMES entry in tests/workflows/test_workflow_naming.py
- remove it from docs/ci/WORKFLOWS.md (link guard), WORKFLOW_SYSTEM.md,
  WORKFLOW_GUIDE.md, DEPENDENCY_TESTING.md; document lockFileMaintenance
  ownership in renovate.json

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske pushed a commit that referenced this pull request Jun 15, 2026
The fleet preset (renovate-presets/fleet.json) has provided the byte-identical
`"pip-compile": {"managerFilePatterns": ["/(^|/)requirements\\.lock$/"]}` block
since #2406, and Workflows extends that preset — so the copy in renovate.json
was dead weight (Renovate merged duplicate manager config to no effect).

Removes the redundant block and refreshes the now-stale description: it still
said "CANARY (do not promote to the fleet preset until proven here)" even though
the manager WAS promoted in #2406. Keeps the lockFileMaintenance / --upgrade
notes from #2413 and the one genuine Workflows-specific override (pip_requirements
disabled for requirements.txt, which is a lock SOURCE here — consumer locks source
pyproject.toml only, which is why that disable is intentionally not in the preset).

Verified: `renovate-config-validator` passes; `renovate --platform=local
--dry-run` still extracts requirements.lock via the preset (depCount 217) with
no error after removal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
stranske added a commit that referenced this pull request Jun 15, 2026
…2417)

The fleet preset (renovate-presets/fleet.json) has provided the byte-identical
`"pip-compile": {"managerFilePatterns": ["/(^|/)requirements\\.lock$/"]}` block
since #2406, and Workflows extends that preset — so the copy in renovate.json
was dead weight (Renovate merged duplicate manager config to no effect).

Removes the redundant block and refreshes the now-stale description: it still
said "CANARY (do not promote to the fleet preset until proven here)" even though
the manager WAS promoted in #2406. Keeps the lockFileMaintenance / --upgrade
notes from #2413 and the one genuine Workflows-specific override (pip_requirements
disabled for requirements.txt, which is a lock SOURCE here — consumer locks source
pyproject.toml only, which is why that disable is intentionally not in the preset).

Verified: `renovate-config-validator` passes; `renovate --platform=local
--dry-run` still extracts requirements.lock via the preset (depCount 217) with
no error after removal.

Co-authored-by: stranske <tim@stranskemo.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant