Skip to content

Add Dependabot auto-merge workflows (ROSA-745)#289

Open
MitaliBhalla wants to merge 1 commit into
openshift:masterfrom
MitaliBhalla:chore/dependabot-auto-merge
Open

Add Dependabot auto-merge workflows (ROSA-745)#289
MitaliBhalla wants to merge 1 commit into
openshift:masterfrom
MitaliBhalla:chore/dependabot-auto-merge

Conversation

@MitaliBhalla
Copy link
Copy Markdown
Contributor

@MitaliBhalla MitaliBhalla commented May 19, 2026

Summary

Dependabot auto-merge for routine updates (ROSA-745 / ROSAENG-751), aligned with openshift/backplane-cli (SREP-2438).

Changes

  • dependabot-auto-merge.yml: auto-merge patch/minor/digest after required CI; majors manual. Uses pull_request_target (no PR checkout), validated GraphQL/REST/comment responses.
  • branch-protection-check.yml: weekly verification of Dependabot config and workflows.

Notes

  • dependabot[bot] + openshift org only.
  • Requires ci/prow/* checks (DPP-20685).

Test plan

  • Required CI green
  • Review YAML

Made with Cursor

Summary by CodeRabbit

  • Chores
    • Added automated repository configuration checks (scheduled and on-demand) to validate Dependabot and workflow setup.
    • Implemented automated dependency update management: patch/minor updates attempt automatic merge with status reporting; major updates are blocked for manual review and a one-time notification is posted when auto-merge is disabled.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Walkthrough

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

Changes

Dependabot Automation Setup

Layer / File(s) Summary
Branch Protection and Health Check Workflow
.github/workflows/branch-protection-check.yml
Weekly/manual workflow that verifies .github/dependabot.yml and .github/workflows/dependabot-auto-merge.yml, enforces expected YAML fields (version, updates, package-ecosystem, directory, trigger, jobs.auto-merge steps), and prints config summaries.
Dependabot Auto-Merge Workflow and Implementation
.github/workflows/dependabot-auto-merge.yml
pull_request_target workflow that runs for dependabot[bot] PRs in openshift; fetches Dependabot metadata, enables SQUASH auto-merge for semver-patch/minor via GraphQL or posts a deduplicated fallback comment on failure, posts a one-time notice for semver-major, and logs the decision.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 12
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: adding Dependabot auto-merge workflows. It is specific, relates directly to the primary purpose of the changeset, and includes a ticket reference (ROSA-745).
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.
Stable And Deterministic Test Names ✅ Passed PR adds workflow YAML files and standard Go tests (using testing.T), not Ginkgo tests. Check for Ginkgo test names is not applicable.
Test Structure And Quality ✅ Passed PR contains no Ginkgo test code—only GitHub Actions workflow YAML files. Custom check for "Ginkgo test code" quality is not applicable.
Microshift Test Compatibility ✅ Passed PR adds only GitHub Actions workflows (YAML), not Ginkgo e2e tests. Custom check applies only to new e2e tests; no applicable test code in PR.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR adds only GitHub Actions workflow YAML files (branch-protection-check.yml, dependabot-auto-merge.yml), not Ginkgo e2e tests. The SNO compatibility check applies only to Ginkgo test additions.
Topology-Aware Scheduling Compatibility ✅ Passed PR adds GitHub Actions workflows (.github/workflows/*.yml) only, not Kubernetes manifests or operator code. No topology-specific scheduling constraints introduced.
Ote Binary Stdout Contract ✅ Passed The PR adds YAML workflow files only. The OTE Binary Stdout Contract check applies to Go test binaries, not YAML configs, making it inapplicable to this PR.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR adds only GitHub Actions YAML workflows, not Ginkgo e2e tests. Custom check applies only to new Go test files, so it is not applicable.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 19, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: MitaliBhalla
Once this PR has been reviewed and has the lgtm label, please assign smarthall for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 77b341a and 8f7a6f0.

📒 Files selected for processing (2)
  • .github/workflows/branch-protection-check.yml
  • .github/workflows/dependabot-auto-merge.yml

Comment thread .github/workflows/branch-protection-check.yml Outdated
Comment thread .github/workflows/dependabot-auto-merge.yml
Comment thread .github/workflows/dependabot-auto-merge.yml Outdated
@MitaliBhalla MitaliBhalla force-pushed the chore/dependabot-auto-merge branch 5 times, most recently from ba68a2c to 63f8427 Compare May 19, 2026 06:18
- 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>
@MitaliBhalla MitaliBhalla force-pushed the chore/dependabot-auto-merge branch from 63f8427 to a772dac Compare May 20, 2026 07:52
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8f7a6f0 and a772dac.

📒 Files selected for processing (2)
  • .github/workflows/branch-protection-check.yml
  • .github/workflows/dependabot-auto-merge.yml

Comment on lines +16 to +17
- name: Checkout code
uses: actions/checkout@v4
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 | ⚡ Quick win

🧩 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.yml

Repository: openshift/deadmanssnitch-operator

Length of output: 160


🏁 Script executed:

cat -n .github/workflows/branch-protection-check.yml

Repository: 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.

Comment on lines +62 to +68
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")
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 | ⚡ Quick win

🧩 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)
PY

Repository: 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.

Suggested change
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.

Comment on lines +26 to +28
if: |
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
steps.metadata.outputs.update-type == 'version-update:semver-minor'
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 | 🟡 Minor | ⚡ Quick win

🧩 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 -30

Repository: 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 -50

Repository: 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.yml

Repository: 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 -A2

Repository: 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 -200

Repository: 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 -A2

Repository: 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.yml

Repository: 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:


🏁 Script executed:

# Check if there's a PR description or additional context in commit message
git log -1 --format="%B" a772dac

Repository: 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.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 20, 2026

@MitaliBhalla: all tests passed!

Full PR test history. Your PR dashboard.

Details

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

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