Skip to content

feat: add auto-fix option for automatic clang-format fixing#443

Draft
shenxianpeng wants to merge 2 commits into
mainfrom
feature/auto-fix
Draft

feat: add auto-fix option for automatic clang-format fixing#443
shenxianpeng wants to merge 2 commits into
mainfrom
feature/auto-fix

Conversation

@shenxianpeng

@shenxianpeng shenxianpeng commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

Closes #439

Adds an auto-fix option that automatically applies clang-format fixes and commits them back to the PR branch, eliminating the manual fix-and-repush cycle.

Changes

action.yml

  • New input auto-fix (default false): When enabled, passes --fix to cpp-linter and runs git auto-commit
  • New input auto-fix-commit-msg (default style: apply styling format fix): Custom commit message for auto-fix commits
  • "Run cpp-linter" step: Conditionally appends --fix arg when auto-fix=true
  • New "Auto-commit clang-format fixes" step: After linter runs:
    1. Checks for git changes
    2. Commits as github-actions[bot]
    3. Pushes to the PR branch
    4. Push failures degrade to warnings (not errors)

Docs

  • README.md: Added auto-fix usage section with example, including [skip ci] tip
  • docs/action.yml: Added metadata for new inputs (min-version 2.19.0, permissions)
  • docs/permissions.md: Added auto-fix permissions section (contents: write)
  • docs/examples/index.md: Added auto-fix recipe
  • .github/workflows/examples/auto-fix.yml: New example workflow

Dependencies

Requires cpp-linter/cpp-linter#202 (adds --fix CLI flag to cpp-linter).

Design Decisions

Decision Rationale
Always fix the entire file clang-format cannot target specific line ranges with -i
Use github-actions[bot] as author Standard practice for automated commits
No [skip ci] in default message Users opt-in via custom auto-fix-commit-msg
Push failure → warning, not error Graceful degradation; branch protection may block push
Auto-fix doesn't affect comment/review logic Format issues are fixed before comments are posted, so no format-related comments appear

@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Jun 8, 2026

@2bndy5 2bndy5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Some notes.

I also think that the PR reviews should not have the full patch (from each tool used) in the review's summary comment, especially if this feature is an option.

Comment thread action.yml
Comment on lines +514 to +515
^git config user.name 'github-actions[bot]'
^git config user.email '41898282+github-actions[bot]@users.noreply.github.com'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Better to use the env vars present: GITHUB_ACTOR and GITHUB_ACTOR_ID. This way, the commits will be associated with the user that triggered the event for the workflow's run.

Suggested change
^git config user.name 'github-actions[bot]'
^git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
^git config user.name $"($env.GITHUB_ACTOR)"
^git config user.email $"($env.GITHUB_ACTOR_ID)+($env.GITHUB_ACTOR)@users.noreply.github.com"

Also, this can be done for a single git commit command instead of all git commands in the CI workflow:

let git_user = $"user.name=($env.GITHUB_ACTOR)"
let git_email = $"user.email=($env.GITHUB_ACTOR_ID)+($env.GITHUB_ACTOR)@users.noreply.github.com"

^git -c $git_user -c $git_email commit -m $commit_msg

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I am not sure if the outside contributor can commit with their own user/email in GitHub actions.
If it's not a problem. It seems good. othersie use a bot user like github-actions[bot] dependabot[bot], pre-commit-ci[bot] are also not bad.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

github-actions[bot] would be good enough if the GITHUB_TOKEN env var is never supplied a PAT (personal access token). If using a PAT, then the owner of the PAT will not be the github-actions[bot].

By using the GITHUB_ACTOR(_ID), we can at least point to the committer that caused violations to be auto-fixed with a new commit.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I am not sure if the outside contributor can commit with their own user/email in GitHub actions

I do this all the time with my automated publishing scripts. See the nu script I wrote for publishing packages from cpp-linter-rs

Comment thread action.yml
} else {
'${{ inputs.auto-fix-commit-msg }}'
}
^git commit -m $"($commit_msg)"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

See my previous comment about setting the user name and email of a single git command.

Comment thread action.yml
if: inputs.auto-fix == 'true' || inputs.auto-fix == true
shell: nu {0}
run: |
let has_changes = (^git diff --exit-code) | complete | $in.exit_code != 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If this returns true, then it is because cpp-linter left some cache artifacts behind. Currently, cpp-linter makes sure the scanned source files are unchanged. Any changes are done in memory or in cache. If changes are done to the C/C++ sources, then they are undone before exiting run_clang_format() or run_clang_tidy().

This feature needs special handling in cpp-linter first; see cpp-linter/cpp-linter#82 for a discussion of the complexity that hasn't been addressed yet.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Oh sorry, I didn't see you submitted cpp-linter/cpp-linter#202

Comment thread action.yml
'--jobs=${{ inputs.jobs }}'
]
if '${{ inputs.auto-fix }}' == 'true' {
$args = ($args | append ['--fix'])

@2bndy5 2bndy5 Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The self-test CI fails here because all variables are immutable by default in nushell. To declare them mutable, use mut instead of let (above this line):

-       let args = [
+       mut args = [

@2bndy5 2bndy5 removed the bug Something isn't working label Jun 9, 2026
…rmat fixes

Adds two new inputs:
- auto-fix: runs cpp-linter --fix and auto-commits changes
- fix-commit-msg: custom commit message (default: 'style: apply styling format fix')

The auto-fix workflow:
1. Runs cpp-linter with --fix (applies clang-format -i)
2. If there are changed files, commits and pushes as github-actions[bot]
3. Push failures degrade to a warning

Closes #439
@github-actions github-actions Bot added the bug Something isn't working label Jun 9, 2026
Comment thread docs/permissions.md
contents: write # (1)!
```

1. Needed to commit and push the formatted changes back to the PR branch.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should also note that this permission is only needed by the token used in actions/checkout (which defaults to github.token).

However, the github.token is NOT able to trigger new CI runs when used to push a commit. If users want the auto-fix commit to trigger a new CI run, then they need to provide it with a PAT that has contents: write permission.

- uses: actions/checkout@v6
  with:
    # MY_TOKEN must have `contents: write` permission.
    # using default token does not trigger CI runs on `git push`
    token: ${{ secrets.MY_TOKEN }}

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

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support auto-fix option to fix code format automatically in PR?

2 participants