ci: add workflow to auto-regenerate licenses for Dependabot PRs#387
ci: add workflow to auto-regenerate licenses for Dependabot PRs#387svor wants to merge 2 commits into
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Valerii Svydenko <vsvydenk@redhat.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: svor The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
📝 WalkthroughWalkthroughAdds a GitHub Actions workflow that runs on Dependabot PRs to regenerate license metadata with up to 3 retries, parses ChangesDependabot License Update
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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: 3
🤖 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/dependabot-license.yml:
- Around line 32-35: Replace the floating action tag "uses:
actions/setup-node@v4" with a pinned commit SHA to mitigate supply-chain risks:
locate the workflow step that currently reads uses: actions/setup-node@v4 (the
block that also sets node-version: 24) and update the uses value to the full
actions/setup-node@<commit-sha> for the intended release (verify the correct SHA
for v4.1.0 or the latest secure release first), ensuring the rest of the step
(node-version: 24) remains unchanged.
- Around line 26-30: Update the Checkout step using the actions/checkout usage
by adding persist-credentials: false to prevent the GH token from being written
to local git config and replace the floating tag actions/checkout@v4 with a
pinned reference to the specific commit SHA (the secure SHA matching v4.2.2 or
current vetted SHA) so the workflow points to an immutable release; modify the
Checkout step block (the uses: actions/checkout entry) to include the new
persist-credentials key and change the uses value to the commit-pinned ref.
- Line 24: The workflow currently only checks "if: github.actor ==
'dependabot[bot]'" which can be spoofed; update the conditional to also verify
the sender is a GitHub App bot by adding a check for "github.event.sender.type
== 'Bot'" (e.g. "if: github.actor == 'dependabot[bot]' &&
github.event.sender.type == 'Bot'") and optionally tighten further by verifying
"github.event.sender.login == 'dependabot[bot]'" so both the actor and sender
type/login are validated.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6690f0c2-c7c6-455d-8ae0-746b69f4f52c
📒 Files selected for processing (1)
.github/workflows/dependabot-license.yml
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.head_ref }} | ||
| fetch-depth: 0 |
There was a problem hiding this comment.
Security: Prevent credential persistence and pin action version.
Two security concerns:
- Missing
persist-credentials: falseallows the GitHub token to persist in the local git config, potentially leaking through artifacts or logs. - The action reference should be pinned to a specific commit SHA hash to prevent supply chain attacks.
🔒 Recommended security hardening
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
+ persist-credentials: falseNote: The commit SHA corresponds to actions/checkout@v4.2.2. Verify the latest secure version before applying.
📝 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.
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.head_ref }} | |
| fetch-depth: 0 | |
| - name: Checkout | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| ref: ${{ github.head_ref }} | |
| fetch-depth: 0 | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 26-30: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 27-27: 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/dependabot-license.yml around lines 26 - 30, Update the
Checkout step using the actions/checkout usage by adding persist-credentials:
false to prevent the GH token from being written to local git config and replace
the floating tag actions/checkout@v4 with a pinned reference to the specific
commit SHA (the secure SHA matching v4.2.2 or current vetted SHA) so the
workflow points to an immutable release; modify the Checkout step block (the
uses: actions/checkout entry) to include the new persist-credentials key and
change the uses value to the commit-pinned ref.
| - name: Use Node 24 | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 24 |
There was a problem hiding this comment.
Security: Pin action to commit SHA.
The action reference should be pinned to a specific commit SHA hash to prevent supply chain attacks.
🔒 Recommended fix
- name: Use Node 24
- uses: actions/setup-node@v4
+ uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 24Note: The commit SHA corresponds to actions/setup-node@v4.1.0. Verify the latest secure version before applying.
📝 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.
| - name: Use Node 24 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| - name: Use Node 24 | |
| uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 | |
| with: | |
| node-version: 24 |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 33-33: 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/dependabot-license.yml around lines 32 - 35, Replace the
floating action tag "uses: actions/setup-node@v4" with a pinned commit SHA to
mitigate supply-chain risks: locate the workflow step that currently reads uses:
actions/setup-node@v4 (the block that also sets node-version: 24) and update the
uses value to the full actions/setup-node@<commit-sha> for the intended release
(verify the correct SHA for v4.1.0 or the latest secure release first), ensuring
the rest of the step (node-version: 24) remains unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Valerii Svydenko <vsvydenk@redhat.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
.github/workflows/dependabot-license.yml (3)
43-83:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFinal attempt parses
problems.mdand mutates exclusion files but never retries or commits.On attempt 3,
yarn license:generatefails → the loop parses problems and appends to.deps/EXCLUDED/*.md→ then hits theattempt -eq MAX_ATTEMPTSbranch andexit 1. Because the step exits non‑zero, the subsequentCommit and push changesstep is skipped (defaultif: success()), so those last‑attempt additions are computed but thrown away. Either skip the parse on the final attempt, or run the parse, retry once more, and only fail after that final retry.🛠️ Suggested control flow
if yarn license:generate; then echo "License generation succeeded." break fi + if [ "$attempt" -eq "$MAX_ATTEMPTS" ]; then + echo "::error::Failed to resolve all dependencies after $MAX_ATTEMPTS attempts." + exit 1 + fi + if [ ! -f .deps/problems.md ]; then echo "::error::License generation failed but no problems.md found." exit 1 fi @@ echo "| \`${PKG}\` | transitive dependency |" >> "$EXCLUDED_FILE" echo "Added $PKG to $EXCLUDED_FILE" done < .deps/problems.md - - if [ "$attempt" -eq "$MAX_ATTEMPTS" ]; then - echo "::error::Failed to resolve all dependencies after $MAX_ATTEMPTS attempts." - exit 1 - fi done🤖 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/dependabot-license.yml around lines 43 - 83, The final-attempt logic currently parses .deps/problems.md and mutates .deps/EXCLUDED/*.md even when attempt == MAX_ATTEMPTS, then immediately exits so the “Commit and push changes” step never runs; change the control flow in the retry loop around yarn license:generate so that either (A) you skip parsing/appending when attempt == MAX_ATTEMPTS (only parse on intermediate failures), or (B) after parsing on the penultimate attempt you perform one additional retry (i.e., only treat failure as terminal after parsing+one more yarn license:generate attempt), ensuring that additions to the .deps/EXCLUDED files are only made when a subsequent attempt will occur or are committed before exiting; refer to the loop variables MAX_ATTEMPTS and attempt, the yarn license:generate invocation, the .deps/problems.md parsing block and the EXCLUDED file writes when implementing the change.
69-77:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAppend may corrupt the table if the excluded file lacks a trailing newline.
echo ... >> "$EXCLUDED_FILE"concatenates onto the last line when the file doesn't already end with\n, producing a row like| existing |\n| \pkg` | … |` glued to the previous one and breaking the markdown table. Ensure a newline boundary before appending (or check for trailing newline first).🛠️ Proposed change
- echo "| \`${PKG}\` | transitive dependency |" >> "$EXCLUDED_FILE" + # Ensure the file ends with a newline before appending a new row + if [ -s "$EXCLUDED_FILE" ] && [ "$(tail -c1 "$EXCLUDED_FILE" | wc -l)" -eq 0 ]; then + printf '\n' >> "$EXCLUDED_FILE" + fi + printf '| `%s` | transitive dependency |\n' "$PKG" >> "$EXCLUDED_FILE" echo "Added $PKG to $EXCLUDED_FILE"🤖 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/dependabot-license.yml around lines 69 - 77, The append to EXCLUDED_FILE using echo ... >> "$EXCLUDED_FILE" can glue the new table row to the previous line if the file lacks a trailing newline; update the loop that writes to EXCLUDED_FILE (using the EXCLUDED_FILE, SECTION, PKG variables and the input .deps/problems.md) to ensure a newline boundary before appending—either check for a trailing newline and add one if missing or write a newline first when creating/appending to EXCLUDED_FILE so the markdown table row is always on its own line.
85-93:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
git diff --quiet .deps/misses untracked files; newly created entries won't be committed.
git diffonly inspects tracked files. Ifyarn license:generateproduces new files under.deps/(e.g. a brand newEXCLUDED/*.mdor a new per-package file), this check returns 0 and the step exits before staging/committing them, silently dropping the work. Usegit status --porcelain(orgit add -Nbefore the diff) to also catch untracked entries.🛠️ Proposed change
- git diff --quiet .deps/ && exit 0 - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]`@users.noreply.github.com`" - git add .deps/ - git commit -s -m "chore(deps): regenerate license dependencies" - git push + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]`@users.noreply.github.com`" + git add .deps/ + if git diff --cached --quiet -- .deps/; then + echo "No .deps/ changes to commit." + exit 0 + fi + git commit -s -m "chore(deps): regenerate license dependencies" + git 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/dependabot-license.yml around lines 85 - 93, The step currently uses the command git diff --quiet .deps/ which only detects changes to tracked files and will miss newly created/untracked files; replace that check with a command that also detects untracked entries (for example run git add -N .deps/ to stage intention-to-add files then run git diff --quiet -- .deps/ or use git status --porcelain .deps/ and test for non-empty output) so that newly generated files under .deps/ are detected and the subsequent git add/.commit steps run; update the step that runs git diff --quiet .deps/ accordingly and keep the existing git add .deps/, git commit, and git push commands.
♻️ Duplicate comments (2)
.github/workflows/dependabot-license.yml (2)
26-30:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
actions/checkoutto a commit SHA and disable credential persistence.Still applicable on the current revision:
actions/checkout@v4is unpinned, and withoutpersist-credentials: falsethe GITHUB_TOKEN is written into the local git config and can leak through subsequent steps or artifacts. Note this will also require an explicit token on thegit pushstep (e.g. via a remote URL with${{ secrets.GITHUB_TOKEN }}or by re-running checkout with credentials only where needed).🤖 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/dependabot-license.yml around lines 26 - 30, Update the actions/checkout usage to pin the action to a specific commit SHA instead of the version tag (replace uses: actions/checkout@v4 with the full SHA) and add persist-credentials: false to the with: block to prevent GITHUB_TOKEN from being written to git config; keep ref: ${{ github.head_ref }} and fetch-depth: 0 as needed, and ensure any later git push step uses an explicit token (e.g., include the secrets.GITHUB_TOKEN in the remote URL or re-run a checkout step with credentials only where required).
32-35:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
actions/setup-nodeto a commit SHA.Same supply‑chain concern as previously raised —
actions/setup-node@v4is still floating.🤖 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/dependabot-license.yml around lines 32 - 35, The workflow currently uses the floating tag "actions/setup-node@v4" which should be pinned to a commit SHA; update the "uses" entry replacing actions/setup-node@v4 with a specific commit SHA (actions/setup-node@<commit-sha>) for the version that supports node-version: 24, fetch the correct SHA from the actions/setup-node v4 release (or GitHub Actions marketplace), and commit that SHA so the runner pulls an immutable reference instead of the floating tag.
🧹 Nitpick comments (1)
.github/workflows/dependabot-license.yml (1)
12-19: ⚡ Quick winAdd a concurrency group to serialize runs per PR.
Each
synchronizeevent will start a new run that fetches, parsesproblems.md, and pushes to the same branch. Without a concurrency group, two in‑flight runs can race on the same.deps/EXCLUDED/*.mdfiles and produce duplicate appends or a non-fast-forward push.♻️ Proposed change
on: pull_request: types: [opened, synchronize] branches: - main +concurrency: + group: dependabot-license-${{ github.event.pull_request.number }} + cancel-in-progress: true + permissions: contents: write🤖 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/dependabot-license.yml around lines 12 - 19, Add a top-level concurrency stanza to the workflow to serialize runs per PR: add a concurrency key with a group value that uses the PR identifier (for example "dependabot-license-${{ github.event.pull_request.number }}") and set cancel-in-progress: false so runs queue instead of canceling; this ensures the workflow (affecting .deps/EXCLUDED/*.md) runs one-at-a-time per pull_request and prevents race conditions between synchronize events.
🤖 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.
Outside diff comments:
In @.github/workflows/dependabot-license.yml:
- Around line 43-83: The final-attempt logic currently parses .deps/problems.md
and mutates .deps/EXCLUDED/*.md even when attempt == MAX_ATTEMPTS, then
immediately exits so the “Commit and push changes” step never runs; change the
control flow in the retry loop around yarn license:generate so that either (A)
you skip parsing/appending when attempt == MAX_ATTEMPTS (only parse on
intermediate failures), or (B) after parsing on the penultimate attempt you
perform one additional retry (i.e., only treat failure as terminal after
parsing+one more yarn license:generate attempt), ensuring that additions to the
.deps/EXCLUDED files are only made when a subsequent attempt will occur or are
committed before exiting; refer to the loop variables MAX_ATTEMPTS and attempt,
the yarn license:generate invocation, the .deps/problems.md parsing block and
the EXCLUDED file writes when implementing the change.
- Around line 69-77: The append to EXCLUDED_FILE using echo ... >>
"$EXCLUDED_FILE" can glue the new table row to the previous line if the file
lacks a trailing newline; update the loop that writes to EXCLUDED_FILE (using
the EXCLUDED_FILE, SECTION, PKG variables and the input .deps/problems.md) to
ensure a newline boundary before appending—either check for a trailing newline
and add one if missing or write a newline first when creating/appending to
EXCLUDED_FILE so the markdown table row is always on its own line.
- Around line 85-93: The step currently uses the command git diff --quiet .deps/
which only detects changes to tracked files and will miss newly
created/untracked files; replace that check with a command that also detects
untracked entries (for example run git add -N .deps/ to stage intention-to-add
files then run git diff --quiet -- .deps/ or use git status --porcelain .deps/
and test for non-empty output) so that newly generated files under .deps/ are
detected and the subsequent git add/.commit steps run; update the step that runs
git diff --quiet .deps/ accordingly and keep the existing git add .deps/, git
commit, and git push commands.
---
Duplicate comments:
In @.github/workflows/dependabot-license.yml:
- Around line 26-30: Update the actions/checkout usage to pin the action to a
specific commit SHA instead of the version tag (replace uses:
actions/checkout@v4 with the full SHA) and add persist-credentials: false to the
with: block to prevent GITHUB_TOKEN from being written to git config; keep ref:
${{ github.head_ref }} and fetch-depth: 0 as needed, and ensure any later git
push step uses an explicit token (e.g., include the secrets.GITHUB_TOKEN in the
remote URL or re-run a checkout step with credentials only where required).
- Around line 32-35: The workflow currently uses the floating tag
"actions/setup-node@v4" which should be pinned to a commit SHA; update the
"uses" entry replacing actions/setup-node@v4 with a specific commit SHA
(actions/setup-node@<commit-sha>) for the version that supports node-version:
24, fetch the correct SHA from the actions/setup-node v4 release (or GitHub
Actions marketplace), and commit that SHA so the runner pulls an immutable
reference instead of the floating tag.
---
Nitpick comments:
In @.github/workflows/dependabot-license.yml:
- Around line 12-19: Add a top-level concurrency stanza to the workflow to
serialize runs per PR: add a concurrency key with a group value that uses the PR
identifier (for example "dependabot-license-${{ github.event.pull_request.number
}}") and set cancel-in-progress: false so runs queue instead of canceling; this
ensures the workflow (affecting .deps/EXCLUDED/*.md) runs one-at-a-time per
pull_request and prevents race conditions between synchronize events.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0b584e61-48e8-44df-953a-1580ee2ff1a8
📒 Files selected for processing (1)
.github/workflows/dependabot-license.yml
Summary
Summary by CodeRabbit