Add Dependabot auto-merge workflows (ROSA-745)#289
Conversation
WalkthroughAdds two GitHub Actions workflows: a weekly/manual branch-protection check that validates Dependabot configuration, and a pull_request_target workflow that enables auto-merge for safe Dependabot updates or posts deduplicated comments for failures and major updates. ChangesDependabot Automation Setup
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 12✅ Passed checks (12 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: MitaliBhalla 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 |
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/branch-protection-check.yml:
- Around line 43-73: The current "Check Required Workflows" step only verifies
file existence (variable required_workflows) and must be extended to validate
actual branch protection and required status checks via the GitHub API; update
the script block to call the API (using gh api or curl with GITHUB_TOKEN) to
fetch branch protection for the default/target branch and assert
required_status_checks.contexts and required_pull_request_reviews settings are
present (and that any required contexts include the expected workflow names like
".github/workflows/dependabot-auto-merge.yml"), fail the job if protection is
absent or required contexts differ, and keep the file-existence checks for a
combined validation. Ensure you reference the same step ("Check Required
Workflows") and variables (required_workflows, all_present) so the new API
validation is added after the existing loop and causes exit 1 on mismatch.
In @.github/workflows/dependabot-auto-merge.yml:
- Around line 20-24: The GitHub Action step "Fetch Dependabot Metadata"
currently uses the mutable reference dependabot/fetch-metadata@v2 (id:
metadata); replace that floating tag with a full-length commit SHA for the
action (e.g., dependabot/fetch-metadata@<full-commit-sha>) to pin the exact code
executed, keeping the step name "Fetch Dependabot Metadata" and id "metadata"
unchanged; you may append a short comment like "# v2" after the SHA for
readability.
- Around line 26-30: Add a guard before calling enablePullRequestAutoMerge that
uses the workflow's checks: read permission to verify branch protection or
required status checks include the ci/prow/* pattern (or wait for those checks
to be reported/passing); specifically, after the semver gate
(steps.metadata.outputs.update-type) call the GitHub API to fetch the target
branch protection / required status checks for the PR branch and ensure
ci/prow/* is present (or poll list of check-runs for the PR until ci/prow/*
checks exist and are successful) and only then invoke
enablePullRequestAutoMerge; update the step that currently calls
enablePullRequestAutoMerge to skip/exit with a clear message when ci/prow/* is
not configured or not passing.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: f359558b-c33b-4d41-a78a-0de7283c3e55
📒 Files selected for processing (2)
.github/workflows/branch-protection-check.yml.github/workflows/dependabot-auto-merge.yml
ba68a2c to
63f8427
Compare
- Auto-merge patch/minor/digest after CI; majors manual - pull_request_target with validated API responses - branch-protection-check for config/workflow presence Co-authored-by: Cursor <cursoragent@cursor.com>
63f8427 to
a772dac
Compare
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/branch-protection-check.yml:
- Around line 16-17: The checkout step using actions/checkout@v4 should be
hardened: replace the loose version reference (actions/checkout@v4) with the
repository SHA-pinned ref (use the exact action commit SHA) and add the input
persist-credentials: false under the checkout step to prevent Git credential
persistence; update the step that references actions/checkout@v4 so the uses
line points at the pinned SHA and add a with block containing
persist-credentials: false.
- Around line 62-68: The workflow validation in the branch-protection check is
reading the YAML trigger with wf.get("on"), but yaml.safe_load() may coerce the
unquoted on key to boolean True. Update the check in the workflow verification
logic to handle both key forms when inspecting the loaded mapping, and keep the
pull_request_target validation anchored in the same branch-protection workflow
parser flow so valid workflows are not rejected.
In @.github/workflows/dependabot-auto-merge.yml:
- Around line 26-28: The workflow's if condition that checks
steps.metadata.outputs.update-type for 'version-update:semver-patch' and
'version-update:semver-minor' does not cover digest-only updates even though the
commit message claims "patch/minor/digest"; either update the commit/message to
remove "digest" or extend the if condition to explicitly handle Dependabot
digest updates (e.g., recognize the digest-related update-type emitted by your
metadata step or a custom flag), by adjusting the check on
steps.metadata.outputs.update-type to include the digest value your metadata
step produces or by adding a separate conditional branch that gates auto-merge
for digest updates.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 71c61ef1-098f-4c50-baa6-6d97d840150f
📒 Files selected for processing (2)
.github/workflows/branch-protection-check.yml.github/workflows/dependabot-auto-merge.yml
| - name: Checkout code | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find unpinned actions and verify credential persistence setting.
rg -nP '^\s*uses:\s*[^@]+@v[0-9]+(\.[0-9]+)*\s*$' .github/workflows
rg -nP '^\s*persist-credentials:\s*false\s*$' .github/workflows/branch-protection-check.ymlRepository: openshift/deadmanssnitch-operator
Length of output: 160
🏁 Script executed:
cat -n .github/workflows/branch-protection-check.ymlRepository: openshift/deadmanssnitch-operator
Length of output: 4239
Harden checkout step: pin action SHA and disable credential persistence.
actions/checkout@v4 is not SHA-pinned and defaults to persisting credentials in git config. Even with read-only permissions, explicitly disabling credential persistence reduces the attack surface.
🔒 Proposed hardening
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@<full-commit-sha>
+ with:
+ persist-credentials: false🧰 Tools
🪛 zizmor (1.25.2)
[warning] 16-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 17-17: 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/branch-protection-check.yml around lines 16 - 17, The
checkout step using actions/checkout@v4 should be hardened: replace the loose
version reference (actions/checkout@v4) with the repository SHA-pinned ref (use
the exact action commit SHA) and add the input persist-credentials: false under
the checkout step to prevent Git credential persistence; update the step that
references actions/checkout@v4 so the uses line points at the pinned SHA and add
a with block containing persist-credentials: false.
| with workflow_path.open() as f: | ||
| wf = yaml.safe_load(f) | ||
| if not isinstance(wf, dict): | ||
| fail("dependabot-auto-merge.yml must be a YAML mapping") | ||
| on = wf.get("on") | ||
| if not isinstance(on, dict) or "pull_request_target" not in on: | ||
| fail("dependabot-auto-merge.yml must use pull_request_target trigger") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether `on` is parsed as string key or boolean key in current repo file.
python3 - <<'PY'
from pathlib import Path
import yaml
p = Path(".github/workflows/dependabot-auto-merge.yml")
wf = yaml.safe_load(p.read_text())
print("keys:", list(wf.keys()) if isinstance(wf, dict) else type(wf))
print("has_string_on:", isinstance(wf, dict) and "on" in wf)
print("has_bool_true_key:", isinstance(wf, dict) and True in wf)
PYRepository: openshift/deadmanssnitch-operator
Length of output: 166
Fix PyYAML key coercion issue in workflow trigger detection.
The yaml.safe_load() method coerces the unquoted on: key to boolean True in the actual workflow file, causing wf.get("on") to return None. This causes the validation to incorrectly fail for valid workflows.
The verification confirms the issue exists: the workflow file's keys are ['name', True, 'permissions', 'jobs'], with True (boolean) instead of "on" (string).
Proposed fix
with workflow_path.open() as f:
wf = yaml.safe_load(f)
if not isinstance(wf, dict):
fail("dependabot-auto-merge.yml must be a YAML mapping")
- on = wf.get("on")
+ trigger = wf.get("on")
+ if trigger is None and True in wf: # PyYAML may coerce `on` -> True
+ trigger = wf.get(True)
- if not isinstance(on, dict) or "pull_request_target" not in on:
+ if not isinstance(trigger, dict) or "pull_request_target" not in trigger:
fail("dependabot-auto-merge.yml must use pull_request_target trigger")📝 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.
| with workflow_path.open() as f: | |
| wf = yaml.safe_load(f) | |
| if not isinstance(wf, dict): | |
| fail("dependabot-auto-merge.yml must be a YAML mapping") | |
| on = wf.get("on") | |
| if not isinstance(on, dict) or "pull_request_target" not in on: | |
| fail("dependabot-auto-merge.yml must use pull_request_target trigger") | |
| with workflow_path.open() as f: | |
| wf = yaml.safe_load(f) | |
| if not isinstance(wf, dict): | |
| fail("dependabot-auto-merge.yml must be a YAML mapping") | |
| trigger = wf.get("on") | |
| if trigger is None and True in wf: # PyYAML may coerce `on` -> True | |
| trigger = wf.get(True) | |
| if not isinstance(trigger, dict) or "pull_request_target" not in trigger: | |
| fail("dependabot-auto-merge.yml must use pull_request_target trigger") |
🤖 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/branch-protection-check.yml around lines 62 - 68, The
workflow validation in the branch-protection check is reading the YAML trigger
with wf.get("on"), but yaml.safe_load() may coerce the unquoted on key to
boolean True. Update the check in the workflow verification logic to handle both
key forms when inspecting the loaded mapping, and keep the pull_request_target
validation anchored in the same branch-protection workflow parser flow so valid
workflows are not rejected.
| if: | | ||
| steps.metadata.outputs.update-type == 'version-update:semver-patch' || | ||
| steps.metadata.outputs.update-type == 'version-update:semver-minor' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check dependabot/fetch-metadata docs for digest update-type values
curl -sS "https://raw.githubusercontent.com/dependabot/fetch-metadata/main/README.md" | grep -A5 -i "update-type\|digest" | head -30Repository: openshift/deadmanssnitch-operator
Length of output: 998
🏁 Script executed:
# Read the workflow file to see full context
cat -n .github/workflows/dependabot-auto-merge.yml | head -50Repository: openshift/deadmanssnitch-operator
Length of output: 2305
🏁 Script executed:
# Also check if there's a line 231 mentioned in the review
wc -l .github/workflows/dependabot-auto-merge.ymlRepository: openshift/deadmanssnitch-operator
Length of output: 125
🏁 Script executed:
# Search for references to digest in the workflow file
rg -i "digest" .github/workflows/dependabot-auto-merge.yml -B2 -A2Repository: openshift/deadmanssnitch-operator
Length of output: 59
🏁 Script executed:
# Read the rest of the workflow file to see full context
cat -n .github/workflows/dependabot-auto-merge.yml | tail -200Repository: openshift/deadmanssnitch-operator
Length of output: 10404
🏁 Script executed:
# Search for any reference to update types or catch-all logic in the workflow
rg "update-type|catch|default|else" .github/workflows/dependabot-auto-merge.yml -B2 -A2Repository: openshift/deadmanssnitch-operator
Length of output: 1954
🏁 Script executed:
# Check git log for PR description or commit messages
git log --oneline -10 -- .github/workflows/dependabot-auto-merge.ymlRepository: openshift/deadmanssnitch-operator
Length of output: 132
🌐 Web query:
Dependabot update-type digest-only Docker image
💡 Result:
Dependabot does not currently have a user-facing “update-type digest-only” option for Docker image dependencies. Instead, digest handling is governed by (a) whether a Docker image reference already includes a digest and (b) how Dependabot classifies “version updates” (SemVer) for the tag part; there is also an internal/experimental capability to pin digests even for tag-only images. 1) What “update-type digest-only” would mean Dependabot’s documented update-types (version-update:semver-patch|minor|major) only control semantic version levels for “version updates” and do not provide a dedicated “digest-only” update type for Docker images [1][2]. 2) Dockerfile syntax matters: digest presence changes what Dependabot can update Dependabot’s digest pinning/update logic has historically depended on whether the existing FROM ...:tag reference already contains a digest @sha256:.... In Dependabot Core, digest pinning/update logic is specifically about “pinning digests” for Docker tag-only images vs updating digests when they already exist in the manifest/reference. An experimental flag (docker_pin_digests) was added to make Dependabot add digests to tag-only Docker images and to append an @sha256:... digest when the old image had no digest but the new one does [3]. Also, there are reported issues where digest-pinned references did not yield the expected PR behavior in certain scenarios, reinforcing that digest handling isn’t controlled by an explicit “digest-only update-type” switch [4]. 3) How to achieve “digest-only” behavior (practically) Because there is no explicit “digest-only” update-type, the closest practical approaches are: A) Ensure you pin by digest, then control updates via what Dependabot treats as the “version” A Dependabot issue discussion notes that attempts to “keep the same version… and update only the digest” used ignore rules plus update-types (SemVer levels) for the dependency name, but the outcome depended on how the digest/tag was interpreted as the patch/minor/major component of the version [5]. This indicates “digest-only” behavior is an emergent effect of Dependabot’s version classification, not a native digest-only update-type. B) Enable/use digest pinning (experimental) so Dependabot can add digests If your goal is for Dependabot to convert tag-only references to digest-pinned ones, there is evidence of an experiment flag (docker_pin_digests) in Dependabot Core that enables adding digests to tag-only images [3]. However, that experiment is not shown in the public dependabot.yml documentation surfaced here, so treat it as non-standard unless your setup explicitly enables Dependabot experiments. Bottom line - No documented “update-type digest-only” value exists for Dependabot Docker updates; update-types are SemVer level controls for version updates [1][2]. - Digest pinning/update for Docker images depends on whether digests are already present, and Dependabot Core has added an experimental capability to pin digests for tag-only images via docker_pin_digests [3]. - Any “digest-only” results you see via ignore/update-types happen indirectly through Dependabot’s versioning rules for the tag portion [5].
Citations:
- 1: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
- 2: https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference
- 3: Add digest pinning for Docker images dependabot/dependabot-core#14071
- 4: No pull request is created if a digest SHA is used to identify a docker-image dependabot/dependabot-core#4419
- 5: [Docker] stay on specific tag and update digest only dependabot/dependabot-core#1971
🏁 Script executed:
# Check if there's a PR description or additional context in commit message
git log -1 --format="%B" a772dacRepository: openshift/deadmanssnitch-operator
Length of output: 337
Discrepancy between commit message and implementation regarding digest updates.
The commit message states "Auto-merge patch/minor/digest after CI," but the condition at lines 26-28 only handles version-update:semver-patch and version-update:semver-minor. Dependabot does not provide a standard update-type value for digest-only updates; digest handling is complex and depends on whether digests are already pinned in the reference.
Either clarify that digest updates are expected to come through as patch/minor updates (depending on tag versioning), or update the commit message if digest auto-merge is not intended.
🤖 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-auto-merge.yml around lines 26 - 28, The
workflow's if condition that checks steps.metadata.outputs.update-type for
'version-update:semver-patch' and 'version-update:semver-minor' does not cover
digest-only updates even though the commit message claims "patch/minor/digest";
either update the commit/message to remove "digest" or extend the if condition
to explicitly handle Dependabot digest updates (e.g., recognize the
digest-related update-type emitted by your metadata step or a custom flag), by
adjusting the check on steps.metadata.outputs.update-type to include the digest
value your metadata step produces or by adding a separate conditional branch
that gates auto-merge for digest updates.
|
@MitaliBhalla: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Summary
Dependabot auto-merge for routine updates (ROSA-745 / ROSAENG-751), aligned with openshift/backplane-cli (SREP-2438).
Changes
pull_request_target(no PR checkout), validated GraphQL/REST/comment responses.Notes
dependabot[bot]+openshiftorg only.Test plan
Made with Cursor
Summary by CodeRabbit