Skip to content

CI: auto-fix and commit clang-format violations instead of just failing - #98

Merged
wruwami merged 4 commits into
mainfrom
ci/auto-fix-clang-format
Jul 24, 2026
Merged

CI: auto-fix and commit clang-format violations instead of just failing#98
wruwami merged 4 commits into
mainfrom
ci/auto-fix-clang-format

Conversation

@wruwami

@wruwami wruwami commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • The lint job's clang-format step used to be --dry-run --Werror only: a formatting slip failed the whole build and needed someone to notice, run clang-format -i locally, and push again. clang-format's output is fully deterministic given .clang-format, so there's no judgment call for a human to make - just run it and push.
  • Now runs clang-format -i for real and, if that changed anything, commits and pushes it back to the branch that triggered the run (the PR's actual head branch for pull_request events, not the synthetic refs/pull/N/merge ref actions/checkout defaults to - that isn't a real branch to push to). The lint job's own permissions: block is bumped to contents: write for this (other jobs are untouched).
  • Pushing re-triggers the workflow, but the second run finds nothing left to fix and doesn't push again, so this is self-terminating.
  • Only works for same-repo branches/PRs, since a fork PR's GITHUB_TOKEN can't push back to the fork - the push step fails closed there (correctly still blocking the check) rather than silently skipping enforcement, so cppcheck/build jobs still gate the PR as before.

Test plan

  • .github/workflows/ci.yml YAML parses cleanly (python3 -c "import yaml; yaml.safe_load(...)").
  • This is a CI-workflow-only change (no C++/build changes), so it can only really be verified by CI itself running on this PR - watching to confirm the clang-format step behaves as intended (no-op here, since this branch's files are already formatted).

Generated by Claude Code

Summary by CodeRabbit

  • Chores
    • Updated automated formatting to apply fixes automatically for C/C++ files (including source, headers, tests, and examples).
    • When formatting changes are made, the results are committed and pushed back to the relevant branch/PR so checks pass without manual intervention.
  • CI
    • Improved CI workflow handling to ensure formatting/verification steps operate against the correct ref, and adjusted permissions to support the automated push behavior.

The lint job's clang-format step used to be --dry-run --Werror only: a
formatting slip failed the whole build and needed someone to notice,
run clang-format -i locally, and push again. clang-format's output is
fully deterministic given .clang-format, so there's no judgment call
for a human to make - just run it and push.

Now runs clang-format -i for real and, if that changed anything,
commits and pushes it back to the branch that triggered the run
(the PR's actual head branch for pull_request events, not the
synthetic refs/pull/N/merge ref actions/checkout defaults to - that
isn't a real branch to push to). The lint job's own permissions block
is bumped to contents: write for this (other jobs are untouched).

Pushing re-triggers the workflow, but the second run finds nothing
left to fix and doesn't push again, so this is self-terminating. Only
works for same-repo branches/PRs, since a fork PR's GITHUB_TOKEN can't
push back to the fork - the push step fails closed there rather than
silently skipping enforcement, so cppcheck/build jobs still gate the
PR as before.
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e7b590d-1487-4527-a74c-78b399df3283

📥 Commits

Reviewing files that changed from the base of the PR and between c0cd25f and 0a391f2.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci.yml

Walkthrough

The lint workflow explicitly checks out the PR or pushed branch, formats C/C++ files in place with clang-format, and commits and pushes detected formatting changes using the GitHub Actions bot identity.

Changes

Lint auto-fix workflow

Layer / File(s) Summary
Lint permissions and branch checkout
.github/workflows/ci.yml
The lint job receives repository content write access and explicitly checks out the PR head or pushed branch.
Format, commit, and push changes
.github/workflows/ci.yml
clang-format now modifies configured C/C++ files in place, detects changes, and pushes a bot-authored commit when formatting differs.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant actionsCheckout
  participant clangFormat
  participant Repository
  GitHubActions->>actionsCheckout: checkout github.head_ref || github.ref_name
  actionsCheckout->>Repository: load branch contents
  GitHubActions->>clangFormat: format C/C++ files in place
  clangFormat-->>GitHubActions: report detected changes
  GitHubActions->>Repository: commit and push formatting updates
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main CI change: auto-fixing, committing, and pushing clang-format violations instead of only failing.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/auto-fix-clang-format

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

@amazon-q-developer amazon-q-developer Bot left a comment

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.

Summary

This PR successfully implements auto-fixing of clang-format violations in the CI workflow, replacing the previous fail-only approach. The implementation correctly handles:

  • Permission escalation scoped to the lint job only
  • Proper branch reference for PR workflows
  • Self-terminating commit loop (second run finds nothing to fix)
  • Graceful failure for fork PRs (can't push back, correctly blocks)

The core logic is sound and tested. The approach eliminates manual formatting round-trips while maintaining enforcement for fork contributions.

Note: I've flagged some variable quoting practices in the shell script that could theoretically cause issues with filenames containing spaces. However, for typical C++ project conventions (no spaces in source filenames), the current implementation functions correctly. Consider these suggestions as defensive improvements rather than blocking issues.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml
git diff/git add against the unquoted $files word list could silently
miss a changed file if a filename ever contained a space (this project
doesn't have any, but no reason to leave the sharp edge). Diff/add the
whole directories instead - clang-format itself still runs file-by-file
via $files, which is fine either way, since a missed word there would
just mean that one file wasn't reformatted, not a silently-dropped fix.
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 4

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

34-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the clang-format version before claiming cross-release stability.

.clang-format makes a fixed formatter invocation deterministic, but the installed clang-format version is not pinned. LLVM releases change formatting options and behavior, so a runner/package update can create unexpected formatting commits. (clang.llvm.org)

Pin the package/toolchain version or use a versioned formatter container/action.

🤖 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/ci.yml around lines 34 - 42, Pin the clang-format
toolchain used by the workflow before relying on its deterministic formatting
behavior. Update the clang-format installation or invocation in the workflow to
use a specific package version or versioned formatter container/action, while
preserving the existing .clang-format-driven auto-fix flow.
🤖 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/ci.yml:
- Around line 49-56: Update the clang-format auto-fix step to store the find
results as a NUL-delimited array, preserving filenames containing whitespace or
glob characters. Use the array safely in the clang-format, git diff, and git add
commands via "${files[@]}", while retaining the existing formatting and commit
flow.
- Around line 57-58: Update the workflow step containing the git commit and push
commands to pass the branch ref through the step’s env configuration, then
reference that environment variable in the git push command with shell quoting.
Remove direct github.head_ref/github.ref_name interpolation from the run script
while preserving the existing push target behavior.
- Around line 43-48: Update the workflow’s formatting push step to authenticate
with a non-GITHUB_TOKEN credential, such as the configured GitHub App or PAT
secret, so the formatting commit triggers a new workflow run. Ensure checkout
does not persist the default workflow token for this push path, while preserving
the existing fail-closed behavior for fork pull requests.
- Around line 19-29: Update the Checkout step’s ref expression to use
github.event.pull_request.head.sha for pull_request events, while retaining
github.ref_name for push events. Replace the current github.head_ref fallback in
the actions/checkout configuration so fork PRs always check out the submitted
commit.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 34-42: Pin the clang-format toolchain used by the workflow before
relying on its deterministic formatting behavior. Update the clang-format
installation or invocation in the workflow to use a specific package version or
versioned formatter container/action, while preserving the existing
.clang-format-driven auto-fix flow.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 48c4d47c-5654-44da-902f-574a0c09c668

📥 Commits

Reviewing files that changed from the base of the PR and between 988313e and c0cd25f.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
…litting

- Pass the target branch name through env: instead of interpolating it
  directly into the run: shell block, per CodeRabbit's template-injection
  flag on github.head_ref/ref_name.
- Replace the unquoted $(find ...) word-splitting with a NUL-delimited
  mapfile + "${files[@]}" array, used consistently by clang-format, git
  diff, and git add, closing the gap the previous whole-directory-diff
  workaround only partially covered.

Did not adopt persist-credentials: false (this job's own git push step
needs that credential) or checkout-by-head.sha (no fork-PR contributions
in this repo's history to defend against).

wruwami commented Jul 24, 2026

Copy link
Copy Markdown
Owner Author

Reviewed the remaining open threads:

  • Amazon Q's 3 $files quoting comments are superseded by the mapfile -d ''/"${files[@]}" rewrite in 0a391f2 (already fully quoted, NUL-delimited).
  • CodeRabbit's checkout-by-head.sha suggestion (fork-PR robustness): not adopting. This repo has no fork-PR contributions in its history — same-account branches only — so github.head_ref resolving to a real branch in this repo is a safe assumption here.
  • CodeRabbit's GITHUB_TOKEN-doesn't-retrigger-workflows note: correct, but not adopting a GitHub App/PAT for it. Worst case is a stale-looking pending check after an auto-fix commit that clears on the next push or a manual re-run — not worth provisioning a privileged credential to close a cosmetic gap.

Resolving these threads accordingly.


Generated by Claude Code

@wruwami
wruwami merged commit 5da90af into main Jul 24, 2026
13 checks passed
@wruwami
wruwami deleted the ci/auto-fix-clang-format branch July 24, 2026 02:51
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.

2 participants