Skip to content

[build] simplify commit-changes workflow#17503

Open
titusfortner wants to merge 5 commits into
trunkfrom
commit-changes
Open

[build] simplify commit-changes workflow#17503
titusfortner wants to merge 5 commits into
trunkfrom
commit-changes

Conversation

@titusfortner
Copy link
Copy Markdown
Member

Current code is doing a lot of work to manage a conditional that does not matter.
Just always push when requested.

This change is needed for a renovate fix I'm working on.

🤖 AI assistance

  • No substantial AI assistance used
  • AI assisted (complete below)
    • Tool(s):
    • What was generated:
    • I reviewed all AI output and can explain the change

🔄 Types of changes

  • Bug fix (backwards compatible)

@titusfortner titusfortner requested a review from Copilot May 18, 2026 17:57
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Simplify commit-changes workflow with unconditional push logic

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Simplify commit-changes workflow logic and error handling
• Remove unnecessary conditional checks for artifact download
• Always push changes when requested, regardless of conditions
• Streamline git operations by removing redundant error exits
Diagram
flowchart LR
  A["Download artifact"] --> B["Configure git user"]
  B --> C["Check if patch exists"]
  C --> D["Apply patch and commit"]
  D --> E["Determine push target"]
  E --> F["Push to branch or origin"]
  F --> G["Output committed status"]
Loading

Grey Divider

File Changes

1. .github/workflows/commit-changes.yml ✨ Enhancement +12/-36

Streamline git workflow with simplified conditionals

• Removed early exit when artifact download fails, allowing workflow to continue
• Simplified nested conditionals for patch application and git operations
• Moved git user configuration before patch application
• Removed individual error handling for apply, commit, and push operations
• Changed push logic to always execute when PUSH_BRANCH is set or changes were committed
• Removed DOWNLOAD_OUTCOME environment variable dependency

.github/workflows/commit-changes.yml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented May 18, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (3)

Grey Divider


Action required

1. PUSH_BRANCH not validated 📘 Rule violation ⛨ Security ⭐ New
Description
PUSH_BRANCH is derived from external workflow inputs (push-branch and now also ref) and used
to construct a force-pushed git push destination refspec, but it is not validated/sanitized as a
safe branch name. Malformed or non-branch values (e.g., containing : or being a tag/PR ref/commit
SHA) can cause the push to fail or target an unintended ref namespace/ref, which is especially risky
with force-push behavior.
Code

.github/workflows/commit-changes.yml[59]

+          PUSH_BRANCH: ${{ inputs.push-branch || inputs.ref || github.ref_name }}
Evidence
PR Compliance ID 10 requires validating external/config inputs early to avoid unchecked assumptions,
yet the workflow sets PUSH_BRANCH directly from `inputs.push-branch || inputs.ref ||
github.ref_name` without any validation even though it determines the push destination. Because
inputs.ref is documented/used as a generic ref to checkout (which may be a tag ref, PR ref, or
commit SHA) and is now part of the fallback chain for PUSH_BRANCH, it can be propagated into `git
push --force origin HEAD:"$PUSH_BRANCH"`, where a non-branch or refspec-like value can either fail
the push or direct it to an unintended ref namespace/target.

.github/workflows/commit-changes.yml[59-59]
.github/workflows/commit-changes.yml[14-18]
.github/workflows/commit-changes.yml[53-53]
Best Practice: Learned patterns

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

## Issue description
`PUSH_BRANCH` is built from external inputs and used as the destination ref in a force-push `git push` refspec, but it is not validated/sanitized to ensure it is a safe, expected branch name. The current fallback to `inputs.ref` (a generic “Git ref to checkout”) can propagate non-branch values (tag/PR ref/commit SHA) or refspec characters (e.g., `:`) into the push destination, risking failures or unintended pushes.

## Issue Context
PR Compliance ID 10 expects validation of external/config-derived inputs early to avoid unchecked assumptions. This workflow force-pushes using `PUSH_BRANCH` as the destination, so the value must be branch-like and should not be coupled to a generic checkout ref unless it is strictly validated (e.g., only accept `refs/heads/*` or plain branch names) and rejected otherwise with a deterministic, actionable error.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[59-59]

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


2. PUSH_BRANCH defaults to github.ref_name ✓ Resolved 📘 Rule violation ⛨ Security
Description
The workflow checks out ${{ inputs.ref || github.ref }} but defaults PUSH_BRANCH to
github.ref_name, which can diverge when callers pass an explicit inputs.ref (notably on
pull_request, where github.ref_name can be a merge ref). This mismatch can cause `git push
--force origin HEAD:"$PUSH_BRANCH"` to push the checked-out HEAD into an unintended branch, risking
accidental branch overwrite.
Code

.github/workflows/commit-changes.yml[59]

+          PUSH_BRANCH: ${{ inputs.push-branch || github.ref_name }}
Evidence
The cited workflow logic sets the checkout ref from inputs.ref || github.ref while deriving the
default push target from the run context via inputs.push-branch || github.ref_name, so when a
caller supplies a different ref but omits push-branch, the workflow becomes nondeterministic and
unsafe because it may force-push to a branch name that is not the one checked out. This is
especially problematic for PR-triggered callers (e.g., ci-lint.yml) where github.ref_name may
reflect the PR merge ref name rather than the PR head branch, making the default push target
incorrect and violating the expectation that CI glue validates inputs and behaves safely.

.github/workflows/commit-changes.yml[39-40]
.github/workflows/commit-changes.yml[53-53]
.github/workflows/commit-changes.yml[59-59]
.github/workflows/commit-changes.yml[36-59]
.github/workflows/ci-lint.yml[3-8]
.github/workflows/ci-lint.yml[98-110]
Best Practice: Learned patterns

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 reusable workflow checks out `inputs.ref || github.ref` but defaults `PUSH_BRANCH` to `inputs.push-branch || github.ref_name`, which may not match the ref actually checked out (notably on `pull_request`, where `github.ref_name` can be a merge ref name). This can cause the workflow to run `git push --force origin HEAD:"$PUSH_BRANCH"` against the wrong branch.

## Issue Context
- The workflow checks out `${{ inputs.ref || github.ref }}` but sets `PUSH_BRANCH: ${{ inputs.push-branch || github.ref_name }}`; if a caller provides `inputs.ref` that differs from the called workflow run’s `github.ref_name`, the push target becomes incorrect.
- `ci-lint.yml` calls `commit-changes.yml` on PRs with `ref: ${{ github.event.pull_request.head.ref }}` and does **not** set `push-branch`, so the called workflow uses the problematic default.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[39-40]
- .github/workflows/commit-changes.yml[53-53]
- .github/workflows/commit-changes.yml[59-59]
- .github/workflows/commit-changes.yml[39-59]

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


3. Unconditional git push --force ✓ Resolved 📘 Rule violation ⛨ Security
Description
The workflow force-pushes HEAD to PUSH_BRANCH whenever that input is set, even when
changes.patch is missing/empty and no commit was created. This can reset/overwrite the remote
branch history (accidental data loss), especially because the artifact download is allowed to fail
without stopping the job.
Code

.github/workflows/commit-changes.yml[R64-65]

+          if [ -n "$PUSH_BRANCH" ]; then
+            git push --force origin HEAD:"$PUSH_BRANCH"
Evidence
PR Compliance ID 12 calls for hardening scripts to prevent accidental data loss, and the workflow’s
logic matches a risky pattern: it allows the artifact download to fail (continue-on-error) and
only creates a commit when changes.patch is non-empty, yet it still runs `git push --force origin
HEAD:"$PUSH_BRANCH" whenever PUSH_BRANCH is non-empty regardless of whether committed` is true.
These citations show there is a code path where no patch is applied/committed (including due to a
missing artifact), but the job still force-updates the remote branch pointer to the current local
HEAD, potentially discarding remote commits.

.github/workflows/commit-changes.yml[58-67]
.github/workflows/commit-changes.yml[47-52]
.github/workflows/commit-changes.yml[58-68]
Best Practice: Learned patterns

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 currently runs `git push --force origin HEAD:"$PUSH_BRANCH"` whenever `PUSH_BRANCH` is set, even if `changes.patch` is missing/empty and no commit was created. This can rewrite the remote branch pointer and clobber remote history (accidental data loss), particularly when the patch artifact download fails but the job continues.

## Issue Context
- The workflow tracks whether it created a commit via a `committed=false/true` flag, but the push-to-`PUSH_BRANCH` path is not conditioned on `committed`.
- The patch/artifact download is allowed to fail (`continue-on-error: true`), and commits occur only when `changes.patch` exists/is non-empty.
- As a result, setting `inputs.push-branch` can cause a force-push of the current `HEAD` even when this run produced no changes (or the artifact was missing), effectively resetting/overwriting the target branch.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[47-69]

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



Remediation recommended

4. git apply lacks error logging 📘 Rule violation ◔ Observability
Description
The workflow now runs git apply/git commit (including git apply --index) without emitting
user-friendly ::error:: GitHub annotation messages on failure, reducing diagnosability and
observability in the Actions UI when patch application or committing fails in CI. This removes prior
explicit diagnostic logging without a replacement.
Code

.github/workflows/commit-changes.yml[R53-54]

+          git apply --index changes.patch
+          git commit -m "$COMMIT_MESSAGE"
Evidence
PR Compliance ID 5 requires retaining or adding user-relevant logging in hard-to-debug paths, but
the updated workflow step contains unguarded git apply/git commit lines with no surrounding
::error:: annotations or explanatory structured messages; meanwhile, the repository otherwise uses
::notice:: messaging for workflow clarity, making the absence of targeted error annotations for
these failure-prone commands a regression in operational insight.

AGENTS.md
.github/workflows/commit-changes.yml[53-54]
.github/workflows/commit-changes.yml[46-59]
.github/workflows/ci-lint.yml[89-96]

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 runs `git apply` (including `git apply --index`) and `git commit` without explicit `::error::` annotations, so when these commands fail the step may fail but the Actions UI won’t show clear, targeted error messages explaining what went wrong.

## Issue Context
Previously, failures were surfaced with `::error::...` messages; now failures rely on raw command output. PR Compliance ID 5 expects user-relevant logging for hard-to-debug paths, and other workflows in this repo use structured annotations like `::notice::` for clarity.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[53-54]


Wrap the commands to emit explicit annotations while preserving the simplified flow, e.g.:
- `git apply --index changes.patch || { echo "::error::Failed to apply patch"; exit 1; }`
- `git commit -m "$COMMIT_MESSAGE" || { echo "::error::Failed to commit changes"; exit 1; }`

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


5. COMMIT_MESSAGE not validated 📘 Rule violation ☼ Reliability
Description
COMMIT_MESSAGE comes from workflow inputs but is not validated before use, so an empty/invalid
value can cause git commit to fail with a generic error. Validate early and fail with a
deterministic, actionable message.
Code

.github/workflows/commit-changes.yml[54]

+          git commit -m "$COMMIT_MESSAGE"
Evidence
PR Compliance ID 11 requires validating external/config inputs and throwing deterministic,
descriptive errors; COMMIT_MESSAGE is an input and is used directly in `git commit -m
"$COMMIT_MESSAGE"` without checks, which can fail implicitly and less clearly.

.github/workflows/commit-changes.yml[54-54]
Best Practice: Learned patterns

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

## Issue description
`COMMIT_MESSAGE` is derived from workflow inputs and is used directly in `git commit` without validation.

## Issue Context
Invalid/empty input values should be caught early with deterministic, descriptive errors to make CI failures actionable.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[54-54]

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


6. Missing patch treated as ok ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new guard if [ ! -s changes.patch ]; then treats a missing changes.patch the same as an
intentionally empty patch, so an artifact download failure/misconfiguration can be silently skipped
as “no changes”. Because the download step is continue-on-error: true, this can produce a green
job without indicating that the expected artifact wasn’t applied.
Code

.github/workflows/commit-changes.yml[50]

+          if [ ! -s changes.patch ]; then
Evidence
The download step is allowed to fail without stopping the job, and the new -s check exits
successfully when the patch is missing/empty, masking download failures as successful runs.

.github/workflows/commit-changes.yml[41-52]

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 currently checks only file size (`-s`) and exits 0 when the patch is missing/empty. With `continue-on-error: true` on the download step, an actual artifact download failure can be silently treated as a successful no-op.

## Issue Context
This reusable workflow is invoked from release/CI workflows where a missing patch may indicate an upstream failure or wrong artifact name.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[41-59]

## Suggested fix
- Emit a `::notice::` before exiting when no patch is present.
- Optionally, distinguish:
 - `if [ ! -f changes.patch ]; then ...` (artifact missing)
 - `elif [ ! -s changes.patch ]; then ...` (empty patch)
 and decide whether “missing” should fail or remain a no-op based on intended caller behavior.
- If you want to keep it as a no-op, at minimum log clearly that commit/push is being skipped due to missing/empty patch.

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


View more (1)
7. Output misrepresents push ✓ Resolved 🐞 Bug ≡ Correctness
Description
The reusable workflow output changes-committed is documented as "committed and pushed", but the
job can push (when push-branch is set) while still emitting committed=false, causing callers to
make incorrect decisions.
Code

↗ .github/workflows/commit-changes.yml

      - name: Apply and commit
Evidence
The workflow output is documented as "committed and pushed" but the emitted value is only based on
whether a commit happened, while push behavior can occur independently when PUSH_BRANCH is set.

.github/workflows/commit-changes.yml[24-27]
.github/workflows/commit-changes.yml[58-69]

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 output `changes-committed` is documented as representing whether changes were "committed and pushed", but the step output is derived solely from whether a commit occurred. With the current logic, a push can occur while `committed=false`, violating the output contract.

### Issue Context
- Output documentation indicates both commit and push.
- Push can happen even without a commit when `PUSH_BRANCH` is set.

### Fix Focus Areas
- .github/workflows/commit-changes.yml[24-27]
- .github/workflows/commit-changes.yml[58-69]

### Suggested fix
- Either:
 1) Change logic so `committed` becomes true only after a successful push (and ensure push is only attempted when appropriate), or
 2) Update the output description/name (and optionally add a separate `pushed` output) so consumers can reliably detect what happened.

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


Grey Divider

Previous review results

Review updated until commit e2be623

Results up to commit eb90a86


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)


Action required
1. Unconditional git push --force ✓ Resolved 📘 Rule violation ⛨ Security
Description
The workflow force-pushes HEAD to PUSH_BRANCH whenever that input is set, even when
changes.patch is missing/empty and no commit was created. This can reset/overwrite the remote
branch history (accidental data loss), especially because the artifact download is allowed to fail
without stopping the job.
Code

.github/workflows/commit-changes.yml[R64-65]

+          if [ -n "$PUSH_BRANCH" ]; then
+            git push --force origin HEAD:"$PUSH_BRANCH"
Evidence
PR Compliance ID 12 calls for hardening scripts to prevent accidental data loss, and the workflow’s
logic matches a risky pattern: it allows the artifact download to fail (continue-on-error) and
only creates a commit when changes.patch is non-empty, yet it still runs `git push --force origin
HEAD:"$PUSH_BRANCH" whenever PUSH_BRANCH is non-empty regardless of whether committed` is true.
These citations show there is a code path where no patch is applied/committed (including due to a
missing artifact), but the job still force-updates the remote branch pointer to the current local
HEAD, potentially discarding remote commits.

.github/workflows/commit-changes.yml[58-67]
.github/workflows/commit-changes.yml[47-52]
.github/workflows/commit-changes.yml[58-68]
Best Practice: Learned patterns

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 currently runs `git push --force origin HEAD:"$PUSH_BRANCH"` whenever `PUSH_BRANCH` is set, even if `changes.patch` is missing/empty and no commit was created. This can rewrite the remote branch pointer and clobber remote history (accidental data loss), particularly when the patch artifact download fails but the job continues.

## Issue Context
- The workflow tracks whether it created a commit via a `committed=false/true` flag, but the push-to-`PUSH_BRANCH` path is not conditioned on `committed`.
- The patch/artifact download is allowed to fail (`continue-on-error: true`), and commits occur only when `changes.patch` exists/is non-empty.
- As a result, setting `inputs.push-branch` can cause a force-push of the current `HEAD` even when this run produced no changes (or the artifact was missing), effectively resetting/overwriting the target branch.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[47-69]

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



Remediation recommended
2. Output misrepresents push ✓ Resolved 🐞 Bug ≡ Correctness
Description
The reusable workflow output changes-committed is documented as "committed and pushed", but the
job can push (when push-branch is set) while still emitting committed=false, causing callers to
make incorrect decisions.
Code

↗ .github/workflows/commit-changes.yml

      - name: Apply and commit
Evidence
The workflow output is documented as "committed and pushed" but the emitted value is only based on
whether a commit happened, while push behavior can occur independently when PUSH_BRANCH is set.

.github/workflows/commit-changes.yml[24-27]
.github/workflows/commit-changes.yml[58-69]

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 output `changes-committed` is documented as representing whether changes were "committed and pushed", but the step output is derived solely from whether a commit occurred. With the current logic, a push can occur while `committed=false`, violating the output contract.

### Issue Context
- Output documentation indicates both commit and push.
- Push can happen even without a commit when `PUSH_BRANCH` is set.

### Fix Focus Areas
- .github/workflows/commit-changes.yml[24-27]
- .github/workflows/commit-changes.yml[58-69]

### Suggested fix
- Either:
 1) Change logic so `committed` becomes true only after a successful push (and ensure push is only attempted when appropriate), or
 2) Update the output description/name (and optionally add a separate `pushed` output) so consumers can reliably detect what happened.

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


Results up to commit d08883b


🐞 Bugs (0) 📘 Rule violations (2) 📎 Requirement gaps (0)


Remediation recommended
1. git apply lacks error logging 📘 Rule violation ◔ Observability
Description
The workflow now runs git apply/git commit (including git apply --index) without emitting
user-friendly ::error:: GitHub annotation messages on failure, reducing diagnosability and
observability in the Actions UI when patch application or committing fails in CI. This removes prior
explicit diagnostic logging without a replacement.
Code

.github/workflows/commit-changes.yml[R53-54]

+          git apply --index changes.patch
+          git commit -m "$COMMIT_MESSAGE"
Evidence
PR Compliance ID 5 requires retaining or adding user-relevant logging in hard-to-debug paths, but
the updated workflow step contains unguarded git apply/git commit lines with no surrounding
::error:: annotations or explanatory structured messages; meanwhile, the repository otherwise uses
::notice:: messaging for workflow clarity, making the absence of targeted error annotations for
these failure-prone commands a regression in operational insight.

AGENTS.md
.github/workflows/commit-changes.yml[53-54]
.github/workflows/commit-changes.yml[46-59]
.github/workflows/ci-lint.yml[89-96]

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 runs `git apply` (including `git apply --index`) and `git commit` without explicit `::error::` annotations, so when these commands fail the step may fail but the Actions UI won’t show clear, targeted error messages explaining what went wrong.

## Issue Context
Previously, failures were surfaced with `::error::...` messages; now failures rely on raw command output. PR Compliance ID 5 expects user-relevant logging for hard-to-debug paths, and other workflows in this repo use structured annotations like `::notice::` for clarity.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[53-54]


Wrap the commands to emit explicit annotations while preserving the simplified flow, e.g.:
- `git apply --index changes.patch || { echo "::error::Failed to apply patch"; exit 1; }`
- `git commit -m "$COMMIT_MESSAGE" || { echo "::error::Failed to commit changes"; exit 1; }`

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


2. COMMIT_MESSAGE not validated 📘 Rule violation ☼ Reliability
Description
COMMIT_MESSAGE comes from workflow inputs but is not validated before use, so an empty/invalid
value can cause git commit to fail with a generic error. Validate early and fail with a
deterministic, actionable message.
Code

.github/workflows/commit-changes.yml[54]

+          git commit -m "$COMMIT_MESSAGE"
Evidence
PR Compliance ID 11 requires validating external/config inputs and throwing deterministic,
descriptive errors; COMMIT_MESSAGE is an input and is used directly in `git commit -m
"$COMMIT_MESSAGE"` without checks, which can fail implicitly and less clearly.

.github/workflows/commit-changes.yml[54-54]
Best Practice: Learned patterns

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

## Issue description
`COMMIT_MESSAGE` is derived from workflow inputs and is used directly in `git commit` without validation.

## Issue Context
Invalid/empty input values should be caught early with deterministic, descriptive errors to make CI failures actionable.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[54-54]

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


3. Missing patch treated as ok ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new guard if [ ! -s changes.patch ]; then treats a missing changes.patch the same as an
intentionally empty patch, so an artifact download failure/misconfiguration can be silently skipped
as “no changes”. Because the download step is continue-on-error: true, this can produce a green
job without indicating that the expected artifact wasn’t applied.
Code

.github/workflows/commit-changes.yml[50]

+          if [ ! -s changes.patch ]; then
Evidence
The download step is allowed to fail without stopping the job, and the new -s check exits
successfully when the patch is missing/empty, masking download failures as successful runs.

.github/workflows/commit-changes.yml[41-52]

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 currently checks only file size (`-s`) and exits 0 when the patch is missing/empty. With `continue-on-error: true` on the download step, an actual artifact download failure can be silently treated as a successful no-op.

## Issue Context
This reusable workflow is invoked from release/CI workflows where a missing patch may indicate an upstream failure or wrong artifact name.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[41-59]

## Suggested fix
- Emit a `::notice::` before exiting when no patch is present.
- Optionally, distinguish:
 - `if [ ! -f changes.patch ]; then ...` (artifact missing)
 - `elif [ ! -s changes.patch ]; then ...` (empty patch)
 and decide whether “missing” should fail or remain a no-op based on intended caller behavior.
- If you want to keep it as a no-op, at minimum log clearly that commit/push is being skipped due to missing/empty patch.

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


Results up to commit 8c353bf


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)


Action required
1. PUSH_BRANCH defaults to github.ref_name ✓ Resolved 📘 Rule violation ⛨ Security
Description
The workflow checks out ${{ inputs.ref || github.ref }} but defaults PUSH_BRANCH to
github.ref_name, which can diverge when callers pass an explicit inputs.ref (notably on
pull_request, where github.ref_name can be a merge ref). This mismatch can cause `git push
--force origin HEAD:"$PUSH_BRANCH"` to push the checked-out HEAD into an unintended branch, risking
accidental branch overwrite.
Code

.github/workflows/commit-changes.yml[59]

+          PUSH_BRANCH: ${{ inputs.push-branch || github.ref_name }}
Evidence
The cited workflow logic sets the checkout ref from inputs.ref || github.ref while deriving the
default push target from the run context via inputs.push-branch || github.ref_name, so when a
caller supplies a different ref but omits push-branch, the workflow becomes nondeterministic and
unsafe because it may force-push to a branch name that is not the one checked out. This is
especially problematic for PR-triggered callers (e.g., ci-lint.yml) where github.ref_name may
reflect the PR merge ref name rather than the PR head branch, making the default push target
incorrect and violating the expectation that CI glue validates inputs and behaves safely.

.github/workflows/commit-changes.yml[39-40]
.github/workflows/commit-changes.yml[53-53]
.github/workflows/commit-changes.yml[59-59]
.github/workflows/commit-changes.yml[36-59]
.github/workflows/ci-lint.yml[3-8]
.github/workflows/ci-lint.yml[98-110]
Best Practice: Learned patterns

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 reusable workflow checks out `inputs.ref || github.ref` but defaults `PUSH_BRANCH` to `inputs.push-branch || github.ref_name`, which may not match the ref actually checked out (notably on `pull_request`, where `github.ref_name` can be a merge ref name). This can cause the workflow to run `git push --force origin HEAD:"$PUSH_BRANCH"` against the wrong branch.

## Issue Context
- The workflow checks out `${{ inputs.ref || github.ref }}` but sets `PUSH_BRANCH: ${{ inputs.push-branch || github.ref_name }}`; if a caller provides `inputs.ref` that differs from the called workflow run’s `github.ref_name`, the push target becomes incorrect.
- `ci-lint.yml` calls `commit-changes.yml` on PRs with `ref: ${{ github.event.pull_request.head.ref }}` and does **not** set `push-branch`, so the called workflow uses the problematic default.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[39-40]
- .github/workflows/commit-changes.yml[53-53]
- .github/workflows/commit-changes.yml[59-59]
- .github/workflows/commit-changes.yml[39-59]

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


Qodo Logo

@selenium-ci selenium-ci added the B-build Includes scripting, bazel and CI integrations label May 18, 2026
Comment thread .github/workflows/commit-changes.yml Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR simplifies the reusable commit-changes GitHub Actions workflow by reducing conditional logic around applying a downloaded patch, committing it, and pushing updates (especially when push-branch is provided).

Changes:

  • Simplifies the “apply patch + commit” flow to a single -s changes.patch check and removes explicit error messaging.
  • Changes push behavior to always force-push when push-branch is set (and only push the current branch when a commit was created).
  • Removes the explicit guard that exited early when the artifact download step didn’t succeed.
Comments suppressed due to low confidence (1)

.github/workflows/commit-changes.yml:66

  • PUSH_BRANCH triggers an unconditional git push --force even when no patch was downloaded/applied and no commit was created. If the artifact download fails (it’s continue-on-error) or changes.patch is empty/missing, this can still force-update the target branch to the currently checked-out ref, potentially overwriting an existing remote branch/history. Consider only force-pushing when a commit was created, or use --force-with-lease plus a safety check that the checked-out ref/branch matches the intended push target.
          if [ -n "$PUSH_BRANCH" ]; then
            git push --force origin HEAD:"$PUSH_BRANCH"
          elif [ "$committed" = true ]; then

Comment thread .github/workflows/commit-changes.yml Outdated
Comment on lines 59 to 63
if [ -s changes.patch ]; then
git apply --index changes.patch
git commit -m "$COMMIT_MESSAGE"
committed=true
fi
@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented May 18, 2026

Persistent review updated to latest commit d08883b

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.

Comment thread .github/workflows/commit-changes.yml
Comment on lines 41 to 45
- name: Download patch
id: download
uses: actions/download-artifact@v8
with:
name: ${{ inputs.artifact-name }}
continue-on-error: true
@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented May 18, 2026

Persistent review updated to latest commit 8c353bf

Comment thread .github/workflows/commit-changes.yml Outdated
@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented May 18, 2026

Persistent review updated to latest commit e2be623

DOWNLOAD_OUTCOME: ${{ steps.download.outcome }}
COMMIT_MESSAGE: ${{ inputs.commit-message }}
PUSH_BRANCH: ${{ inputs.push-branch }}
PUSH_BRANCH: ${{ inputs.push-branch || inputs.ref || github.ref_name }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

1. push_branch not validated 📘 Rule violation ⛨ Security

PUSH_BRANCH is derived from external workflow inputs (push-branch and now also ref) and used
to construct a force-pushed git push destination refspec, but it is not validated/sanitized as a
safe branch name. Malformed or non-branch values (e.g., containing : or being a tag/PR ref/commit
SHA) can cause the push to fail or target an unintended ref namespace/ref, which is especially risky
with force-push behavior.
Agent Prompt
## Issue description
`PUSH_BRANCH` is built from external inputs and used as the destination ref in a force-push `git push` refspec, but it is not validated/sanitized to ensure it is a safe, expected branch name. The current fallback to `inputs.ref` (a generic “Git ref to checkout”) can propagate non-branch values (tag/PR ref/commit SHA) or refspec characters (e.g., `:`) into the push destination, risking failures or unintended pushes.

## Issue Context
PR Compliance ID 10 expects validation of external/config-derived inputs early to avoid unchecked assumptions. This workflow force-pushes using `PUSH_BRANCH` as the destination, so the value must be branch-like and should not be coupled to a generic checkout ref unless it is strictly validated (e.g., only accept `refs/heads/*` or plain branch names) and rejected otherwise with a deterministic, actionable error.

## Fix Focus Areas
- .github/workflows/commit-changes.yml[59-59]

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations Compliance violation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants