Add Dependabot auto-merge workflows (ROSA-745)#448
Conversation
WalkthroughAdds a scheduled branch-protection validation workflow that verifies Dependabot config and the auto-merge workflow, and a Dependabot auto-merge workflow that conditionally enables GitHub auto-merge for safe updates, posts deduped comments for failures and major updates, and logs decisions. ChangesDependabot Automation and Validation
sequenceDiagram
participant DependabotBot as dependabot[bot]
participant AutoMergeWF as dependabot-auto-merge workflow
participant RepoREST as GitHub REST API
participant RepoGraphQL as GitHub GraphQL API
participant Repository as Repository (PR)
DependabotBot->>AutoMergeWF: PR opened / synchronize (pull_request_target)
AutoMergeWF->>AutoMergeWF: fetch dependabot metadata, determine update type
AutoMergeWF->>RepoREST: GET PR -> node_id
AutoMergeWF->>RepoGraphQL: mutation enableAutoMerge(node_id, method=SQUASH)
RepoGraphQL->>AutoMergeWF: success/failure
AutoMergeWF->>Repository: post deduped warning or major-update comment as needed
AutoMergeWF->>AutoMergeWF: log final decision (auto_merge_enabled, update_type)
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: 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/dependabot-auto-merge.yml:
- Around line 27-30: The if condition on steps.metadata.outputs.update-type
includes an invalid value 'version-update:semver-digest'; update the auto-merge
condition by removing that check so only documented outputs remain (keep
'version-update:semver-patch' and 'version-update:semver-minor', and add
'version-update:semver-major' if intended), i.e. edit the multi-line if that
references steps.metadata.outputs.update-type to eliminate the
'version-update:semver-digest' clause and ensure the OR chain only contains
valid update-type strings.
- Around line 108-135: The workflow step "Comment on Major Version Updates"
currently always posts a new comment (using the POST to /issues/.../comments and
jq-built body) on every synchronize event; modify it to first GET existing
comments for the pull request and search for an identifiable marker (e.g., a
unique HTML/comment token or "🚨 **Major Version Update Detected** 🚨" string)
and if found PATCH that existing comment ID instead of POSTing a new one,
otherwise POST as currently implemented; alternatively, add logic to skip this
whole step when the GitHub event is a synchronize by checking github.event_name
or remove synchronize from the workflow triggers—apply the change inside the
same step around the http_code/jq logic so the GH_TOKEN, comment body variables
and POST/PATCH decision are reused.
🪄 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: 2c44ab95-0f87-4c02-a7e6-3c987f0a7e18
📒 Files selected for processing (2)
.github/workflows/branch-protection-check.yml.github/workflows/dependabot-auto-merge.yml
b7efcc5 to
175803d
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>
175803d to
80fe2a8
Compare
|
@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. |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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:
- Line 17: The workflow currently uses the mutable reference "uses:
actions/checkout@v4"; replace that mutable tag with the action's immutable
commit SHA (e.g., "uses: actions/checkout@<commit-sha>") by locating the step
that contains "uses: actions/checkout@v4" and swapping the tag for the pinned
commit hash from the actions/checkout repository's release commit; update any
other actions in the file that use mutable tags similarly and commit the change
so the workflow uses fixed, immutable references.
- Line 22: The workflow installs PyYAML without a version pin (the step
containing "pip install --quiet pyyaml"); change that command to install a
specific, pinned PyYAML release (for example replace it with a pinned version
like pyyaml==6.0) so installs are reproducible and mitigate supply-chain risks,
and update the "pip install --quiet pyyaml" invocation in the
branch-protection-check.yml file accordingly (optionally include a hash or use a
requirements file if you prefer stronger verification).
- Around line 51-52: The current check only ensures the "directory" key exists;
update the validation around entry and i to also ensure entry["directory"] is a
non-empty string (not None, not empty/whitespace, and of type str) before
accepting it; if it fails these checks call fail with a clear message (e.g.,
keep using fail(f"dependabot.yml: updates[{i}] missing directory") or a slightly
adjusted message) so invalid values don't slip through.
- Around line 16-17: Update the "Checkout code" step that uses
actions/checkout@v4 to explicitly set persist-credentials: false to avoid
leaving GitHub token credentials available to later steps; locate the step with
the uses: actions/checkout@v4 entry and add the persist-credentials: false input
under that step so credential persistence is disabled.
In @.github/workflows/dependabot-auto-merge.yml:
- Around line 24-25: The workflow step with id enable-auto-merge calls
enablePullRequestAutoMerge without verifying that ci/prow/* checks exist; add a
fail-closed guard before invoking enablePullRequestAutoMerge by querying the PR
head SHA's check-runs/statuses (e.g., using the Checks API or a GraphQL
statusLookup) and ensure at least one ci/prow/* check-run or required status is
present; if none are found, skip or abort auto-merge to enforce the ci/prow/*
presence. Use the same guard logic for the earlier block referenced (lines
87-113) and keep the step name/id (enable-auto-merge /
enablePullRequestAutoMerge) so the mutation is only called when the check-run
guard passes.
- Around line 24-28: The auto-merge job gating condition in the step with id
enable-auto-merge only checks for semver patch/minor updates and thus misses
digest updates (which yield an empty update-type); update the if condition that
references steps.metadata.outputs.update-type to also accept an empty string by
adding || steps.metadata.outputs.update-type == '' so digest updates are
considered eligible for auto-merge.
🪄 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: 24c3a0a2-f45d-4265-96b4-2ff9c516bc79
📒 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.
Set persist-credentials: false for defense in depth.
Although this workflow only reads the repository, disabling credential persistence prevents potential credential leakage through artifacts or logs.
🛡️ Proposed fix
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@v4
+ with:
+ persist-credentials: false📝 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 code | |
| uses: actions/checkout@v4 | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| 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, Update
the "Checkout code" step that uses actions/checkout@v4 to explicitly set
persist-credentials: false to avoid leaving GitHub token credentials available
to later steps; locate the step with the uses: actions/checkout@v4 entry and add
the persist-credentials: false input under that step so credential persistence
is disabled.
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
Pin action to commit hash for supply chain security.
Using a mutable tag reference (@v4) instead of an immutable commit hash exposes the workflow to potential supply chain attacks if the action's tag is moved or compromised.
🔒 Proposed fix
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2📝 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.
| uses: actions/checkout@v4 | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
🧰 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 at line 17, The workflow
currently uses the mutable reference "uses: actions/checkout@v4"; replace that
mutable tag with the action's immutable commit SHA (e.g., "uses:
actions/checkout@<commit-sha>") by locating the step that contains "uses:
actions/checkout@v4" and swapping the tag for the pinned commit hash from the
actions/checkout repository's release commit; update any other actions in the
file that use mutable tags similarly and commit the change so the workflow uses
fixed, immutable references.
| - name: Validate Dependabot and workflow configuration | ||
| run: | | ||
| set -euo pipefail | ||
| pip install --quiet pyyaml |
There was a problem hiding this comment.
Pin PyYAML version for reproducibility and security.
Installing PyYAML without a version constraint exposes the workflow to potential supply chain risks and non-reproducible builds if a new version introduces breaking changes or vulnerabilities.
📌 Proposed fix
- pip install --quiet pyyaml
+ pip install --quiet pyyaml==6.0.2📝 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.
| pip install --quiet pyyaml | |
| pip install --quiet pyyaml==6.0.2 |
🤖 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 at line 22, The workflow
installs PyYAML without a version pin (the step containing "pip install --quiet
pyyaml"); change that command to install a specific, pinned PyYAML release (for
example replace it with a pinned version like pyyaml==6.0) so installs are
reproducible and mitigate supply-chain risks, and update the "pip install
--quiet pyyaml" invocation in the branch-protection-check.yml file accordingly
(optionally include a hash or use a requirements file if you prefer stronger
verification).
| if "directory" not in entry: | ||
| fail(f"dependabot.yml: updates[{i}] missing directory") |
There was a problem hiding this comment.
Validate directory field value, not just presence.
The check only verifies the directory key exists, but doesn't validate its value. An empty string, None, or non-string value would pass this check but fail Dependabot validation.
✅ Proposed fix
- if "directory" not in entry:
- fail(f"dependabot.yml: updates[{i}] missing directory")
+ if not entry.get("directory"):
+ fail(f"dependabot.yml: updates[{i}] missing or empty directory")📝 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.
| if "directory" not in entry: | |
| fail(f"dependabot.yml: updates[{i}] missing directory") | |
| if not entry.get("directory"): | |
| fail(f"dependabot.yml: updates[{i}] missing or empty directory") |
🤖 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 51 - 52, The
current check only ensures the "directory" key exists; update the validation
around entry and i to also ensure entry["directory"] is a non-empty string (not
None, not empty/whitespace, and of type str) before accepting it; if it fails
these checks call fail with a clear message (e.g., keep using
fail(f"dependabot.yml: updates[{i}] missing directory") or a slightly adjusted
message) so invalid values don't slip through.
| - name: Enable Auto-Merge for Safe Updates | ||
| id: enable-auto-merge |
There was a problem hiding this comment.
ci/prow/* presence is not enforced before auto-merge is enabled.
This path goes from metadata lookup straight to enablePullRequestAutoMerge; there is no status/check-run query anywhere in the job. Any patch/minor Dependabot PR will therefore be put on the auto-merge path even when no ci/prow/* check exists for the head SHA, which is looser than the PR objective. Add a fail-closed guard before the GraphQL mutation.
Also applies to: 87-113
🤖 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 24 - 25, The
workflow step with id enable-auto-merge calls enablePullRequestAutoMerge without
verifying that ci/prow/* checks exist; add a fail-closed guard before invoking
enablePullRequestAutoMerge by querying the PR head SHA's check-runs/statuses
(e.g., using the Checks API or a GraphQL statusLookup) and ensure at least one
ci/prow/* check-run or required status is present; if none are found, skip or
abort auto-merge to enforce the ci/prow/* presence. Use the same guard logic for
the earlier block referenced (lines 87-113) and keep the step name/id
(enable-auto-merge / enablePullRequestAutoMerge) so the mutation is only called
when the check-run guard passes.
| - name: Enable Auto-Merge for Safe Updates | ||
| id: enable-auto-merge | ||
| 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
🌐 Web query:
What output from the current dependabot/fetch-metadata@v2 action should a workflow use to distinguish digest updates from semver patch/minor/major updates?
💡 Result:
To distinguish digest updates from semver (major, minor, patch) updates using the dependabot/fetch-metadata@v2 action, you should use the update-type output [1][2]. The update-type output provides the highest semver change being made by the pull request [1][2]. When Dependabot performs a digest update (e.g., updating a Docker image by its SHA), the update-type output will typically be empty or null, as it does not correspond to a semver version increment [3]. In contrast, semver updates will return values such as: - version-update:semver-major [1] - version-update:semver-minor [1] - version-update:semver-patch [1] To implement this in a GitHub Actions workflow, you can check the value of this output [1]: - To target semver updates: if: ${{ steps.dependabot-metadata.outputs.update-type!= '' }} - To target digest updates (where update-type is null or empty): if: ${{ steps.dependabot-metadata.outputs.update-type == '' }} Note that for more complex scenarios, such as grouped updates or specific package ecosystems, you may also want to inspect the updated-dependencies-json output, which provides a detailed JSON structure containing the full information about each updated dependency, including the previous and new versions [1][2].
Citations:
- 1: https://github.com/dependabot/fetch-metadata
- 2: https://github.com/step-security/dependabot-fetch-metadata
- 3: Fetch Metadata action returns null update-type output for pull requests dependabot/fetch-metadata#339
🏁 Script executed:
# Look for any PR description, issue, or documentation that states the objective
git log --oneline --all -20Repository: openshift/certman-operator
Length of output: 1528
🏁 Script executed:
# Check for any documentation about the workflow's intended behavior
fd -t f -e md | xargs rg -l "digest.*auto" -i 2>/dev/null || echo "No direct matches for digest auto-merge objective"Repository: openshift/certman-operator
Length of output: 120
🏁 Script executed:
# Check the commit or PR that introduced this workflow
git log --oneline -- ".github/workflows/dependabot-auto-merge.yml" | head -5Repository: openshift/certman-operator
Length of output: 125
🏁 Script executed:
# Get the full commit message for the workflow introduction
git show 80fe2a8 --format=fuller -sRepository: openshift/certman-operator
Length of output: 584
🏁 Script executed:
# Search for any ROSA-745 references or related documentation
rg -i "rosa-745|digest.*update" --type mdRepository: openshift/certman-operator
Length of output: 52
Add digest update detection to the auto-merge gate.
The PR objective explicitly requires patch, minor, and digest updates to auto-merge, but this condition only checks for semver patch/minor. Digest updates produce an empty update-type and will not match either condition, causing them to fall through to the "not eligible" branch.
Add || steps.metadata.outputs.update-type == '' to detect digest updates:
Diff
- name: Enable Auto-Merge for Safe Updates
id: enable-auto-merge
if: |
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
steps.metadata.outputs.update-type == 'version-update:semver-minor' ||
steps.metadata.outputs.update-type == ''🤖 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 24 - 28, The
auto-merge job gating condition in the step with id enable-auto-merge only
checks for semver patch/minor updates and thus misses digest updates (which
yield an empty update-type); update the if condition that references
steps.metadata.outputs.update-type to also accept an empty string by adding ||
steps.metadata.outputs.update-type == '' so digest updates are considered
eligible for auto-merge.
|
On hold — pausing this per-repo workflow rollout while we switch to the boilerplate / MintMaker (Renovate) path for ROSA-745. Please do not merge; we will close or reopen after the platform PR lands. |
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