Skip to content

ci: auto-update bundle manifests on same-repo PRs#3169

Open
rm3l wants to merge 4 commits into
redhat-developer:mainfrom
rm3l:ci/auto-update-bundle-manifests-on-pr
Open

ci: auto-update bundle manifests on same-repo PRs#3169
rm3l wants to merge 4 commits into
redhat-developer:mainfrom
rm3l:ci/auto-update-bundle-manifests-on-pr

Conversation

@rm3l

@rm3l rm3l commented Jul 9, 2026

Copy link
Copy Markdown
Member

Description

Update the PR bundle validation workflow to automatically regenerate and push bundle manifests when they are out of sync. For security, the auto-commit only runs on same-repo PRs (not forks), since fork PR events don't have access to repo secrets.

The auto-commit is best-effort. If the push fails, the workflow falls through to the existing error message guiding manual remediation.

Which issue(s) does this PR fix or relate to

This might be helpful for tagRelease PRs like #3164

PR acceptance criteria

  • Tests
  • Documentation

How to test changes / Special notes to the reviewer

Update the PR bundle validation workflow to automatically regenerate
and push bundle manifests when they are out of sync, using the rhdh-bot
identity so the push triggers CI.

For security, the auto-commit only runs on same-repo PRs (not forks).
It is best-effort — if the push fails, the workflow falls through to the
existing error message guiding manual remediation.

Assisted-by: Claude
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@rm3l rm3l marked this pull request as ready for review July 9, 2026 11:30
@rm3l rm3l requested a review from a team as a code owner July 9, 2026 11:30
@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

ci: auto-update bundle manifests on same-repo PRs

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Regenerate bundle manifests during PR validation and detect meaningful diffs (ignoring createdAt).
• Auto-commit and push regenerated manifests for same-repo PRs using rhdh-bot credentials.
• Keep fork PRs secure by skipping auto-push and preserving the existing remediation failure
 message.
Diagram

graph TD
  B["Checkout PR branch"] --> C["Regenerate bundles"] --> D{"Out of sync?"}
  D -- "No" --> E(["Pass"])
  D -- "Yes" --> F{"Same-repo PR?"}
  F -- "Fork" --> I(["Fail w/ guidance"])
  F -- "Same repo" --> G["Auto-commit & push"] --> D

  subgraph Legend
    direction LR
    _act["Step"] ~~~ _dec{"Decision"} ~~~ _end(["Outcome"])
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use pull_request_target to allow auto-push for forks
  • ➕ Would allow auto-fixing manifests even for fork-based PRs
  • ➕ Simplifies token/checkout branching logic
  • ➖ Significant security risk: executes in base repo context with access to secrets
  • ➖ Requires strict hardening (no untrusted code execution) and ongoing vigilance
2. Upload regenerated manifests as workflow artifact (no commit)
  • ➕ Avoids any write permissions or secret usage for PR validation
  • ➕ Still provides the exact fixed outputs for contributors to apply locally
  • ➖ Does not keep the PR branch automatically up to date
  • ➖ Adds manual steps for authors and may increase iteration time
3. Use a GitHub App with narrowly-scoped permissions for commits
  • ➕ Better security posture than a broad PAT; auditable and revocable
  • ➕ Can be configured with fine-grained repo/permission scopes
  • ➖ More setup/ops overhead than using an existing bot token
  • ➖ Still must avoid enabling writes for forks unless explicitly desired

Recommendation: The current approach is the best balance of developer experience and security: it auto-fixes same-repo PRs (where secrets/tokens are safe to use) while intentionally refusing to write on fork PRs. The best-effort push plus re-check preserves the existing failure guidance when automation can’t complete.

Files changed (1) +35 / -6

Other (1) +35 / -6
pr-bundle-diff-checks.yamlAuto-regenerate and (conditionally) auto-push bundle manifest fixes on PRs +35/-6

Auto-regenerate and (conditionally) auto-push bundle manifest fixes on PRs

• Adds contents:write permission and updates checkout to explicitly target the PR head repo/ref (supporting forks). Regenerates bundle manifests, detects meaningful diffs while ignoring createdAt churn, and conditionally commits/pushes fixes for same-repo PRs using the rhdh-bot token. If changes remain (or the PR is from a fork), the workflow fails with the existing remediation guidance.

.github/workflows/pr-bundle-diff-checks.yaml

@rhdh-qodo-merge

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 18 rules

Grey Divider


Action required

1. Push failure false-green 🐞 Bug ≡ Correctness
Description
The workflow commits regenerated manifests and allows git push to fail (`continue-on-error:
true`), but the subsequent “Fail if…” step only checks the local working tree. If the push fails
after a successful local commit, git diff becomes clean and the job exits 0 even though the PR
branch is still out of sync.
Code

.github/workflows/pr-bundle-diff-checks.yaml[R54-72]

+      - name: Auto-commit and push updated bundle manifests
+        # Only attempt on same-repo PRs (not forks) for security; best-effort — failure falls through to the next step
+        if: steps.check.outputs.changed == 'true' && github.event.pull_request.head.repo.full_name == github.repository
+        continue-on-error: true
+        run: |
+          git config user.name "rhdh-bot"
+          git config user.email "rhdh-bot@redhat.com"
+          git add bundle/ config/ dist/
+          git commit -m "chore: regenerate bundle manifests"
+          git push
+
+      - name: Fail if bundle manifests are out of sync
+        if: steps.check.outputs.changed == 'true'
+        run: |
+          # Re-check in case the auto-commit step already pushed the fix
+          if git diff --quiet -I'^    createdAt: ' bundle config dist; then
+            echo "✅ Bundle manifests were auto-updated and pushed"
            exit 0
          fi
Relevance

⭐⭐ Medium

No direct precedent on push-failure handling; team sometimes tightens false-green CI logic (e.g., PR
#2828).

PR-#2828
PR-#1599

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The auto-commit step commits before pushing and ignores push failure; the later step’s git diff
check only reflects local repository state, so a failed push after a successful commit will still
look “clean” locally and incorrectly pass.

.github/workflows/pr-bundle-diff-checks.yaml[54-72]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow can report success even when the auto-push fails, because it commits locally and then later validates only via `git diff` (local state), not remote state.

### Issue Context
- `continue-on-error: true` makes push failures non-fatal.
- After a successful `git commit`, `git diff` becomes clean even if `git push` failed, causing the subsequent step to incorrectly `exit 0`.

### Fix Focus Areas
- .github/workflows/pr-bundle-diff-checks.yaml[54-72]

### Suggested fix approach
1. Give the auto-commit step an `id` (e.g., `autopush`) and write an output like `pushed=true/false`.
2. If `git push` fails, undo the local commit so the next step still sees a diff and fails (or explicitly fail based on `pushed=false`).
  - Example pattern inside the step:
    - run `git commit ...`
    - `if git push; then echo "pushed=true" >> $GITHUB_OUTPUT; else echo "pushed=false" >> $GITHUB_OUTPUT; git reset --hard HEAD~1; fi`
3. In the “Fail if…” step, only exit 0 when `steps.autopush.outputs.pushed == 'true'` (or otherwise keep failing when `changed=true`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Bot token exposed to PR 🐞 Bug ⛨ Security
Description
On same-repo PRs, actions/checkout uses secrets.RHDH_BOT_TOKEN, and by default persists it in
git credentials for the workspace; then make bundles build-installers runs PR-controlled code in
the same job. This enables PR code to read/exfiltrate the bot token from the checked-out repo’s git
config/credentials.
Code

.github/workflows/pr-bundle-diff-checks.yaml[R23-30]

+      - name: Checkout PR branch
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
+          repository: ${{ github.event.pull_request.head.repo.full_name }}
+          ref: ${{ github.head_ref }}
+          # Use rhdh-bot token for same-repo PRs (enables push); falls back to default for forks
+          token: ${{ secrets.RHDH_BOT_TOKEN || github.token }}
          fetch-depth: 0
Relevance

⭐⭐⭐ High

Team previously hardened workflows to avoid secrets exposure when running PR code (PRs #2293,
#1563).

PR-#2293
PR-#1563

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The checkout step configures a bot token for the repo, and the job later runs make from the PR
branch; with default checkout behavior, those credentials remain available in the workspace during
the build step.

.github/workflows/pr-bundle-diff-checks.yaml[23-30]
.github/workflows/pr-bundle-diff-checks.yaml[37-38]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow injects `RHDH_BOT_TOKEN` during checkout, and `actions/checkout` persists credentials by default; later steps execute PR-controlled code (`make ...`), which can access those persisted credentials.

### Issue Context
This primarily affects **same-repo PRs**, where `secrets.RHDH_BOT_TOKEN` is available and thus actually used.

### Fix Focus Areas
- .github/workflows/pr-bundle-diff-checks.yaml[23-30]
- .github/workflows/pr-bundle-diff-checks.yaml[37-38]
- .github/workflows/pr-bundle-diff-checks.yaml[54-63]

### Suggested fix approach
- Prefer using `github.token` for checkout and set `persist-credentials: false` to avoid leaving credentials in the repo for subsequent steps.
- Only inject `RHDH_BOT_TOKEN` in the auto-push step (scoped via `env:`) and set the remote URL just-in-time for the push, e.g.:
 - `git remote set-url origin https://x-access-token:${RHDH_BOT_TOKEN}@github.com/${{ github.repository }}.git`
 - `git push origin HEAD:${{ github.head_ref }}`
This limits exposure of the bot token to the smallest possible surface area.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ  1 issues published inline · 2 in summary

Qodo Logo

Comment on lines +54 to 72
- name: Auto-commit and push updated bundle manifests
# Only attempt on same-repo PRs (not forks) for security; best-effort — failure falls through to the next step
if: steps.check.outputs.changed == 'true' && github.event.pull_request.head.repo.full_name == github.repository
continue-on-error: true
run: |
git config user.name "rhdh-bot"
git config user.email "rhdh-bot@redhat.com"
git add bundle/ config/ dist/
git commit -m "chore: regenerate bundle manifests"
git push

- name: Fail if bundle manifests are out of sync
if: steps.check.outputs.changed == 'true'
run: |
# Re-check in case the auto-commit step already pushed the fix
if git diff --quiet -I'^ createdAt: ' bundle config dist; then
echo "✅ Bundle manifests were auto-updated and pushed"
exit 0
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Push failure false-green 🐞 Bug ≡ Correctness

The workflow commits regenerated manifests and allows git push to fail (`continue-on-error:
true`), but the subsequent “Fail if…” step only checks the local working tree. If the push fails
after a successful local commit, git diff becomes clean and the job exits 0 even though the PR
branch is still out of sync.
Agent Prompt
### Issue description
The workflow can report success even when the auto-push fails, because it commits locally and then later validates only via `git diff` (local state), not remote state.

### Issue Context
- `continue-on-error: true` makes push failures non-fatal.
- After a successful `git commit`, `git diff` becomes clean even if `git push` failed, causing the subsequent step to incorrectly `exit 0`.

### Fix Focus Areas
- .github/workflows/pr-bundle-diff-checks.yaml[54-72]

### Suggested fix approach
1. Give the auto-commit step an `id` (e.g., `autopush`) and write an output like `pushed=true/false`.
2. If `git push` fails, undo the local commit so the next step still sees a diff and fails (or explicitly fail based on `pushed=false`).
   - Example pattern inside the step:
     - run `git commit ...`
     - `if git push; then echo "pushed=true" >> $GITHUB_OUTPUT; else echo "pushed=false" >> $GITHUB_OUTPUT; git reset --hard HEAD~1; fi`
3. In the “Fail if…” step, only exit 0 when `steps.autopush.outputs.pushed == 'true'` (or otherwise keep failing when `changed=true`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@rhdh-qodo-merge rhdh-qodo-merge Bot added enhancement New feature or request Tests labels Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant