Repository navigation
feat: add a one-step format check sub-action #518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0fb80d8
feat: add a one-step format check sub-action
shenxianpeng 1d7d22a
docs: show the format check first and test it in CI
shenxianpeng 8863766
docs: lead the README Quick start with the format check
shenxianpeng 2058026
fix(format): hash the binary from stdin so Windows paths match
shenxianpeng 589c7c4
fix(format): skip symlinks and refuse a base-branch pull_request_targ…
shenxianpeng 6d1c3a7
fix(format): count only style issues in checks-failed
shenxianpeng File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| --- | ||
| title: Format check | ||
| description: A one-step GitHub Action that fails a pull request or push when the C/C++ lines it changes are not clang-formatted. | ||
| --- | ||
|
|
||
| # Format check | ||
|
|
||
| `cpp-linter/cpp-linter-action/format` checks that the C/C++ lines a pull request or push | ||
| changes follow clang-format, and fails the job when they do not. It is a separate, smaller | ||
| action in this repository: one step, no token, no Python. | ||
|
|
||
| ```yaml | ||
| name: cpp-linter | ||
| on: | ||
| pull_request: | ||
| push: | ||
| branches: [main] | ||
|
|
||
| jobs: | ||
| format: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| - uses: cpp-linter/cpp-linter-action/format@v2 | ||
| ``` | ||
|
|
||
| ## What it does | ||
|
|
||
| 1. Downloads the newest patch release of the clang-format major you ask for (21 by default) | ||
| from [cpp-linter/clang-tools-static-binaries], and checks its SHA-512. | ||
| 2. Works out what changed: | ||
| - `pull_request`: the merge commit that `actions/checkout` checks out, compared with its | ||
| first parent (the base branch). | ||
| - `push`: the pushed commits, compared with the commit before the push (for a new branch, | ||
| with the parent of the last commit). | ||
| - `pull_request_target`: the same, but only when the job checks out the pull request | ||
| (`ref: refs/pull/<number>/merge`); with the default checkout of the base branch the step | ||
| fails and asks for `pull_request` instead. | ||
| - `merge_group`: the merge queue's base commit. | ||
| - Any other event, such as `workflow_dispatch` or `schedule`: every file. | ||
|
|
||
| The base commit is fetched on its own, so the default `fetch-depth: 1` of | ||
| `actions/checkout` is enough. | ||
| 3. Runs `clang-format --dry-run --Werror` on the changed lines of each changed file. | ||
| 4. For every line that is not formatted, adds an error annotation, which shows in the pull | ||
| request's diff view. The step summary lists the files and shows the change clang-format | ||
| would make; the job log has the full diff. | ||
| 5. Fails the step when any file needs formatting. | ||
|
|
||
| Lines the change does not touch are not checked, so an old code base can turn the check on | ||
| without reformatting everything first. | ||
|
|
||
| ## Inputs | ||
|
|
||
| | Input | Default | Description | | ||
| |---|---|---| | ||
| | `version` | `21` | clang-format major version, from 12 to 23. | | ||
| | `style` | `file` | Passed to `clang-format --style`. `file` uses the closest `.clang-format`, and LLVM style when there is none. Any built-in style (`google`, `webkit`, ...) works too. | | ||
| | `extensions` | `c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx` | File extensions to check, comma-separated. | | ||
| | `ignore` | (none) | Paths to skip, separated by `\|` or new lines, as git pathspecs relative to the repository root. `build` skips the `build` directory, `*.pb.cc` skips matching files anywhere. | | ||
| | `files-changed-only` | `true` | Check only the files the pull request or push changes. `false` checks every tracked file with a matching extension. | | ||
| | `lines-changed-only` | `true` | Check only the added or changed lines. `false` checks the whole of each changed file. | | ||
|
|
||
| Files listed in a [`.clang-format-ignore`][clang-format-ignore] file are skipped too, with | ||
| clang-format 18 or later. | ||
|
|
||
| ## Outputs | ||
|
|
||
| | Output | Description | | ||
| |---|---| | ||
| | `checks-failed` | The number of files with style issues. | | ||
| | `clang-format-version` | The full clang-format version used, for example `21.1.8`. | | ||
|
|
||
| The step fails when `checks-failed` is not 0, and also when clang-format itself fails, for | ||
| example on a broken `.clang-format` (those files are not counted in `checks-failed`). To | ||
| report without failing, set `continue-on-error: true` on the step. | ||
|
|
||
| ## Moving from another clang-format action | ||
|
|
||
| Those actions check the whole repository by default. To get the same, set | ||
| `files-changed-only: false`; to check only what each pull request changes, keep the default. | ||
|
|
||
| | [DoozyX/clang-format-lint-action] | This action | | ||
| |---|---| | ||
| | `clangFormatVersion: 18` | `version: 18` (12 to 23) | | ||
| | `style: file` | `style: file` (the default) | | ||
| | `extensions: 'h,cpp'` | `extensions: 'h,cpp'` | | ||
| | `exclude` (paths to skip) | `ignore`, with paths separated by `\|` or new lines | | ||
| | `source: './src'` | not needed; use `ignore` for paths to skip | | ||
| | `inplace: True` | use the main action's [`auto-fix`](inputs-outputs.md#auto-fix) | | ||
|
|
||
| | [jidicula/clang-format-action] | This action | | ||
| |---|---| | ||
| | `clang-format-version: '22'` | `version: '22'` (12 to 23) | | ||
| | `check-path: 'src'` | not needed; use `ignore` for paths to skip | | ||
| | `exclude-regex: '^./third_party/.*$'` | `ignore: 'third_party'` (a pathspec, not a regex) | | ||
| | `include-regex` | `extensions` (a list of extensions, not a regex) | | ||
|
|
||
| ## Runners and limits | ||
|
|
||
| - GitHub-hosted Linux (x64, arm64), macOS and Windows runners work. Self-hosted runners and | ||
| `container:` jobs need `bash`, `git`, `curl` and `jq`. | ||
| - It only reports. For review suggestions, a pull request comment, auto-fix or clang-tidy, | ||
| use the [main action](index.md). | ||
| - `--style=file` reads `.clang-format` files from the checked-out pull request, as | ||
| clang-format does locally. | ||
| - Symbolic links are skipped, so a pull request cannot point clang-format at a file outside | ||
| the checkout. | ||
|
|
||
| [cpp-linter/clang-tools-static-binaries]: https://github.com/cpp-linter/clang-tools-static-binaries | ||
| [clang-format-ignore]: https://clang.llvm.org/docs/ClangFormat.html#clang-format-ignore | ||
| [DoozyX/clang-format-lint-action]: https://github.com/DoozyX/clang-format-lint-action | ||
| [jidicula/clang-format-action]: https://github.com/jidicula/clang-format-action |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| name: C/C++ format check | ||
| description: >- | ||
| Check that the C/C++ lines a pull request or push changes follow clang-format. | ||
| One line to set up, fails the job on style issues, no token needed. | ||
| author: cpp-linter | ||
| branding: | ||
| icon: "check-circle" | ||
| color: "green" | ||
| inputs: | ||
| version: | ||
| description: | | ||
| The clang-format major version to use, from 12 to 23. | ||
| The newest patch release of that major from | ||
| [cpp-linter/clang-tools-static-binaries](https://github.com/cpp-linter/clang-tools-static-binaries) | ||
| is downloaded and its SHA-512 checked. | ||
| required: false | ||
| default: '21' | ||
| style: | ||
| description: | | ||
| The style passed to `clang-format --style`. | ||
| The default `file` uses the closest `.clang-format` file, and LLVM style when there is none. | ||
| required: false | ||
| default: file | ||
| extensions: | ||
| description: The file extensions to check, comma-separated. | ||
| required: false | ||
| default: "c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx" | ||
| ignore: | ||
| description: | | ||
| Paths to skip, separated by `|` or new lines, as git pathspecs relative to the | ||
| repository root: `build` skips the build directory, `*.pb.cc` skips matching files | ||
| anywhere. Files listed in `.clang-format-ignore` are skipped too (clang-format 18+). | ||
| required: false | ||
| default: '' | ||
| files-changed-only: | ||
| description: | | ||
| Check only the files the pull request or push changes. | ||
| Set to `false` to check every tracked file with a matching extension. | ||
| Other events (for example `workflow_dispatch`) always check every file. | ||
| required: false | ||
| default: 'true' | ||
| lines-changed-only: | ||
| description: | | ||
| Check only the lines the pull request or push adds or changes. | ||
| Set to `false` to check the whole of each changed file. | ||
| required: false | ||
| default: 'true' | ||
| outputs: | ||
| checks-failed: | ||
| description: The number of files with style issues. | ||
| value: ${{ steps.check.outputs.checks-failed }} | ||
| clang-format-version: | ||
| description: The full clang-format version that was used, for example `21.1.8`. | ||
| value: ${{ steps.check.outputs.clang-format-version }} | ||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Check C/C++ format | ||
| id: check | ||
| shell: bash | ||
| env: | ||
| INPUT_VERSION: ${{ inputs.version }} | ||
| INPUT_STYLE: ${{ inputs.style }} | ||
| INPUT_EXTENSIONS: ${{ inputs.extensions }} | ||
| INPUT_IGNORE: ${{ inputs.ignore }} | ||
| INPUT_FILES_CHANGED_ONLY: ${{ inputs.files-changed-only }} | ||
| INPUT_LINES_CHANGED_ONLY: ${{ inputs.lines-changed-only }} | ||
| # Only used to fetch the base commit when actions/checkout did not keep its credentials. | ||
| INPUT_TOKEN: ${{ github.token }} | ||
| run: bash "$GITHUB_ACTION_PATH/check.sh" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.