Add automated universal image lockfile refresh workflow#961
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds scheduled and manually triggered GitHub Actions automation for direct or transitive universal image dependency refreshes. It updates direct constraints, recompiles per-image lockfiles, detects changes, replaces outdated mode-specific pull requests, and publishes new pull requests for substantive diffs. Estimated code review effort: 4 (Complex) | ~45 minutes 🚥 Pre-merge checks | ✅ 10✅ Passed checks (10 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (1)
.github/workflows/universal-image-lockfile-refresh.yaml (1)
44-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCron literal duplicated between trigger and mode logic.
"30 6 * * 1"here must stay in sync with the schedule literal on Line 8. If one is edited without the other, the Monday run silently misclassifies astransitive, downgrading a direct-dependency bump to a lockfile-only refresh.🤖 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/universal-image-lockfile-refresh.yaml at line 44, Update the workflow’s schedule-mode logic around the github.event.schedule comparison so it does not duplicate the Monday cron literal from the trigger configuration; centralize or reuse a single schedule value for both trigger and classification, preserving the Monday run’s direct-dependency mode.
🤖 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/universal-image-lockfile-refresh.yaml:
- Line 168: Update the shell step assigning mode near the mode-determination
flow to receive steps.mode.outputs.mode through the step’s env mapping, then
reference the environment variable inside run instead of interpolating the
GitHub Actions output directly. Preserve the existing mode value and downstream
behavior.
- Around line 39-48: Replace direct GitHub Actions expression interpolation in
the “Determine mode” step at
.github/workflows/universal-image-lockfile-refresh.yaml lines 39-48 by passing
github.event_name, github.event.schedule, and inputs.mode through env and
referencing EVENT_NAME, SCHEDULE, and DISPATCH_MODE in the shell script. Apply
the same fix at lines 161-168 by passing steps.mode.outputs.mode through env as
MODE and referencing $MODE instead of interpolating the expression.
- Line 173: Update the git add command in the lockfile refresh workflow to
restrict pyproject.toml and requirements.txt staging to the same
"$IMAGES_DIR"/th*/ flavor pattern used by the bump and refresh loops, preventing
unrelated non-th* files from being included.
- Around line 32-34: Update the actions/checkout step to set
persist-credentials: false so GH_ACCESS_TOKEN is not retained in .git/config
during the job. In the “Create pull request” step, configure the authenticated
remote immediately before the push, using GH_ACCESS_TOKEN only for that
operation.
- Around line 32-37: Update the workflow’s actions/checkout and
astral-sh/setup-uv steps to reference immutable full commit SHAs instead of the
mutable v4 and v6 tags, while preserving their existing configuration and
behavior.
- Around line 76-77: Update the version extraction regex in latest_from_index()
to recognize source distribution filenames such as pkg-1.2.3.tar.gz in addition
to wheel-style -cp/-py artifacts. Preserve the existing version capture and
normalization behavior so both artifact types append the extracted version to
self.versions.
- Line 62: Update the index_url extraction in the lockfile refresh workflow to
read the training image Dockerfile’s --index-url value instead of parsing
pyproject.toml. Preserve the existing directory iteration and downstream
lockfile generation, using the Dockerfile as the authoritative package-index
source.
- Around line 96-105: Update the version replacement logic in the finditer loop
to apply changes only when latest is greater than current, using Version
comparisons for both values. Preserve the existing operator, formatting, and
changed tracking while preventing equal or older mirror versions from rewriting
the dependency pin.
- Around line 82-91: Update the URL lookup exception handler around
urllib.request.urlopen and LinkParser parsing to emit the caught exception to
stderr before returning None. Preserve the existing fallback behavior while
ensuring network, index, and parsing failures are distinguishable from a genuine
absence of versions.
---
Nitpick comments:
In @.github/workflows/universal-image-lockfile-refresh.yaml:
- Line 44: Update the workflow’s schedule-mode logic around the
github.event.schedule comparison so it does not duplicate the Monday cron
literal from the trigger configuration; centralize or reuse a single schedule
value for both trigger and classification, preserving the Monday run’s
direct-dependency mode.
🪄 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: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 600617a6-e56b-497a-91c1-f66c916019b7
📒 Files selected for processing (1)
.github/workflows/universal-image-lockfile-refresh.yaml
9ba4708 to
beaaabd
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.github/workflows/universal-image-lockfile-refresh.yaml (1)
147-148: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winNo validation that the first line of
requirements.txtis actually an--index-url=line before stripping the prefix.If a
requirements.txtever lacks that first line (e.g., a new image flavor added without following the convention, or a prior restore failure),index_urlsilently becomes the full first line — likely a package pin likenumpy==1.26.0— and gets passed touv pip compile --index-url=..., producing a confusing failure far from the actual root cause.🛡️ Fail fast with a clear error
index_url_line=$(head -1 "$dir/requirements.txt") + if [[ "$index_url_line" != --index-url=* ]]; then + echo "::error::$flavor: requirements.txt is missing the leading --index-url= line" + exit 1 + fi index_url="${index_url_line#--index-url=}"🤖 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/universal-image-lockfile-refresh.yaml around lines 147 - 148, Validate index_url_line in the requirements refresh logic before removing the --index-url= prefix. If the first line does not begin with that exact prefix, fail immediately with a clear error identifying the affected requirements file; only assign index_url after validation, preserving the existing compile flow for valid files.
🤖 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/universal-image-lockfile-refresh.yaml:
- Around line 179-190: Update the “Create pull request” step to pass the
repository context through its env block, then use that environment variable in
the git remote URL instead of interpolating `${{ github.repository }}` directly
in the run script. Follow the existing safe environment-variable pattern used
elsewhere in the workflow while preserving the current authentication behavior.
- Around line 22-24: Update the workflow’s concurrency group to include the
refresh mode or triggering schedule, so the daily transitive and weekly direct
cron runs use distinct groups. Preserve cancel-in-progress behavior within each
mode while preventing either Monday trigger from cancelling the other.
---
Nitpick comments:
In @.github/workflows/universal-image-lockfile-refresh.yaml:
- Around line 147-148: Validate index_url_line in the requirements refresh logic
before removing the --index-url= prefix. If the first line does not begin with
that exact prefix, fail immediately with a clear error identifying the affected
requirements file; only assign index_url after validation, preserving the
existing compile flow for valid files.
🪄 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: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 3fb05820-7476-452b-a70b-c346f4a22e47
📒 Files selected for processing (1)
.github/workflows/universal-image-lockfile-refresh.yaml
beaaabd to
c0a2b66
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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/universal-image-lockfile-refresh.yaml:
- Around line 202-214: Move the substantive-change/comment-only validation ahead
of the “Check for existing lockfile PR” step, so comment-only refreshes exit
without closing or deleting the existing PR. Preserve the existing Close
outdated PR behavior for refreshes that contain actual lockfile changes.
- Around line 216-220: Update the publication steps that push changes and run gh
pr create to authenticate with GH_ACCESS_TOKEN instead of GITHUB_TOKEN, while
leaving unrelated workflow steps unchanged. Scope this credential change only to
the push and pull-request creation operations so resulting PR activity triggers
normal CI workflows.
- Around line 110-123: Update the replacement logic in the re.finditer loop to
avoid mutating content while using offsets from the original string. Collect
each changed match’s start/end offsets and replacement text, then apply
replacements in reverse start-offset order, preserving the existing version
comparison and changed logging behavior.
- Around line 19-21: Remove the workflow-level contents: write and
pull-requests: write permissions from universal-image-lockfile-refresh.yaml.
Assign only the minimum required permissions to the publishing job, and separate
lockfile generation or dependency resolution into a read-only job without write
credentials.
- Around line 37-38: Update the “Install uv” workflow step to use a
full-SHA-pinned installer action instead of running pip install uv, and
configure that action with an explicitly locked uv version. Preserve the
existing workflow behavior while ensuring both the action reference and uv
version are pinned.
🪄 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: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 3f81ed1d-846f-4e45-b022-163f7b35f169
📒 Files selected for processing (1)
.github/workflows/universal-image-lockfile-refresh.yaml
c0a2b66 to
3c717d4
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (5)
.github/workflows/universal-image-lockfile-refresh.yaml (5)
33-38:⚠️ Potential issue | 🔴 CriticalPrevent writable-token exposure to an unpinned installer (CWE-522, CWE-829).
Checkout persists the write-capable
GITHUB_TOKENin Git configuration, thenpip install uvruns unpinned PyPI content. Setpersist-credentials: false; install a fixeduvversion through a full-SHA-pinned action or verified artifact.🤖 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/universal-image-lockfile-refresh.yaml around lines 33 - 38, Update the checkout step to set persist-credentials to false, then replace the unpinned pip install in the “Install uv” step with installation of a fixed uv version using a full-SHA-pinned action or verified artifact.Sources: Path instructions, Linters/SAST tools
19-21:⚠️ Potential issue | 🟠 MajorScope write permissions to the publishing job (CWE-284).
Workflow-level
contents: writepluspull-requests: writeexposes a write-capableGITHUB_TOKENto package installation and dependency resolution. Move permissions to a dedicated publishing job; keep refresh work read-only.As per path instructions, “Set least-privilege permissions per job, not workflow level.”
🤖 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/universal-image-lockfile-refresh.yaml around lines 19 - 21, Remove the workflow-level write permissions from universal-image-lockfile-refresh.yaml so refresh and dependency-resolution steps use the default read-only token. Add contents: write and pull-requests: write only to the dedicated publishing job’s permissions, preserving its ability to publish updates while keeping all other jobs least-privileged.Source: Path instructions
202-214:⚠️ Potential issue | 🟠 MajorCheck substantive changes before closing the existing PR.
A comment-only refresh closes and deletes the current PR before the later cached-diff check exits. Perform the comment/timestamp-only check before
Close outdated PR.Also applies to: 249-253
🤖 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/universal-image-lockfile-refresh.yaml around lines 202 - 214, Move the comment/timestamp-only cached-diff check ahead of the “Close outdated PR” step in the workflow, including the corresponding block around the later cached-diff check. Ensure comment-only refreshes exit before invoking gh pr close or deleting PR_BRANCH, while substantive changes retain the existing close-and-delete behavior.
216-261:⚠️ Potential issue | 🟠 MajorUse
GH_ACCESS_TOKENfor publication, includinggit push.
GITHUB_TOKEN-created PRs will not trigger normal CI. SetGH_TOKENtoGH_ACCESS_TOKENand configure the authenticated remote immediately before each push; changingGH_TOKENalone does not authenticategit push.🤖 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/universal-image-lockfile-refresh.yaml around lines 216 - 261, The pull request publication flow must use GH_ACCESS_TOKEN so created PRs trigger normal CI. In the “Create pull request” step, set GH_TOKEN from secrets.GH_ACCESS_TOKEN and, immediately before git push origin "$branch", configure the origin remote to authenticate with that token; retain GH_TOKEN for gh label and gh pr commands.
110-123:⚠️ Potential issue | 🟠 MajorDo not mutate
contentusing stale match offsets.
re.finditeroffsets refer to the original string. Once one replacement changes length, laterm.start()/m.end()values can splice the wrong region and corruptpyproject.toml. Collect replacements and apply them in reverse order, or usere.subwith a callback.🤖 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/universal-image-lockfile-refresh.yaml around lines 110 - 123, The replacement loop using re.finditer and content slicing relies on stale match offsets after earlier edits. Update this logic to collect applicable replacements first and apply them from the end of content toward the beginning, or use re.sub with a callback, while preserving the existing version comparison, logging, and changed behavior.
🤖 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/universal-image-lockfile-refresh.yaml:
- Around line 33-38: Update the checkout step to set persist-credentials to
false, then replace the unpinned pip install in the “Install uv” step with
installation of a fixed uv version using a full-SHA-pinned action or verified
artifact.
- Around line 19-21: Remove the workflow-level write permissions from
universal-image-lockfile-refresh.yaml so refresh and dependency-resolution steps
use the default read-only token. Add contents: write and pull-requests: write
only to the dedicated publishing job’s permissions, preserving its ability to
publish updates while keeping all other jobs least-privileged.
- Around line 202-214: Move the comment/timestamp-only cached-diff check ahead
of the “Close outdated PR” step in the workflow, including the corresponding
block around the later cached-diff check. Ensure comment-only refreshes exit
before invoking gh pr close or deleting PR_BRANCH, while substantive changes
retain the existing close-and-delete behavior.
- Around line 216-261: The pull request publication flow must use
GH_ACCESS_TOKEN so created PRs trigger normal CI. In the “Create pull request”
step, set GH_TOKEN from secrets.GH_ACCESS_TOKEN and, immediately before git push
origin "$branch", configure the origin remote to authenticate with that token;
retain GH_TOKEN for gh label and gh pr commands.
- Around line 110-123: The replacement loop using re.finditer and content
slicing relies on stale match offsets after earlier edits. Update this logic to
collect applicable replacements first and apply them from the end of content
toward the beginning, or use re.sub with a callback, while preserving the
existing version comparison, logging, and changed behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 904a7726-1abd-439b-bd84-860b5d60ba15
📒 Files selected for processing (1)
.github/workflows/universal-image-lockfile-refresh.yaml
451948e to
d3864af
Compare
|
The commit message says But workflow in PR refreshes pins in requirements.txt within existing constraints, so there are no direct dependency bumps. |
Daily transitive dependency refresh for universal training images against the AIPCC PyPI index. Recompiles requirements.txt within existing pyproject.toml constraints — does not bump direct dependencies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d3864af to
6840ba5
Compare
|
@ChughShilpa issues addressed, I have removed label creation, it needs to be created manually (one time action) |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ChughShilpa, sutaakar The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Summary
requirements.txtfor universal training images (images/universal/training/th*/)workflow_dispatchuv pip compile --upgradeper flavor against the AIPCC PyPI index to bump transitive dependencies within existingpyproject.tomlconstraints--index-urlfirst-line preservation quirk ofuv pip compileDoes not modify
pyproject.tomlconstraints — direct dependency bumps remain manual.Test plan
workflow_dispatch— confirm it creates a PR with onlyrequirements.txtchanges--index-urlfirst line is preserved in allrequirements.txtfiles🤖 Generated with Claude Code