Skip to content
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

PS-9040 Integrate clang-tidy checks for Percona server #5196

Merged
merged 1 commit into from
Mar 14, 2024

Conversation

VarunNagaraju
Copy link
Contributor

https://perconadev.atlassian.net/browse/PS-9040

Creates a yaml file for clang-tidy workflow which is triggered on a pull request.

The workflow triggers a run of generating comiplation commands and uses the same to perform a clang-tidy check on the modified files and generates a report of the warnings in the changed code through a github action bot in the form of review comments on the pull request.

Copy link
Collaborator

@inikep inikep left a comment

Choose a reason for hiding this comment

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

LGTM

fetch-depth: 0

- name: Fetch base branch
run: |
Copy link
Collaborator

@percona-ysorokin percona-ysorokin Jan 3, 2024

Choose a reason for hiding this comment

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

Any chance we can re-use actions/checkout@v4 action here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fetching submodules can be added to the checkout step. But, I'm not sure if we can fetch just one more branch(base branch) without fetching all the other unnecessary branches and tags using fetch-depth option.
Also, after checking out to the PR branch, fetching the base branch takes less than a second. So, I don't think it adds any overhead.

- name: Install clang-tidy
run: |
sudo apt-get update
sudo apt-get install -y clang clang-tidy libldap2-dev curl libcurl4-openssl-dev bison libudev-dev libkrb5-dev
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would go with the latest clang-17 here but you will need to add a custom LLVM apt repository first
(https://apt.llvm.org/)

Copy link
Collaborator

@inikep inikep Jan 4, 2024

Choose a reason for hiding this comment

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

In this case please use a variable instead of 17 as we do at:
https://github.com/percona/percona-server/blob/8.0/azure-pipelines.yml#L396-L400
You will also need a variable with a Linux distro name (above we use e.g. UBUNTU_CODE_NAME: focal).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


- name: Prepare compile_commands.json
run: |
cmake -B build -DCMAKE_INSTALL_PREFIX=../install -DWITH_DEBUG=1 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=my_boost \
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • Put build directory out of source tree, say to ../build.
  • Do not use -DWITH_DEBUG directly, use -DCMAKE_BUILD_TYPE=Debug|RelWithDebInfo.
    BTW, it also makes sense to check both Debug and RelWithDebInfo configurations with clang-tidy.
  • Put boost directory out of source, say ../boost. It also makes sense to cache the boost tarball archive using actions/cache@v3 action.
  • For Boolean CMake Options please use ON|OFF instead of ''1|0'
  • For this particular scenario, I think you should use -DWITH_SYSTEM_LIBS=ON for every library possible. Having something bundled just extends build command JSON file with additional items that won't be used.
  • Something is wrong with WITH_CURL option, it points to a binary - just remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • Out of source build dir - Done.
  • Use a cache for boost - Done.
  • Update boolean options to ON/OFF - Done.
  • Use DWITH_SYSTEM_LIBS=ON - Done.
  • Remove curl option - Done.

Regarding checking for both Debug and RelWithDebInfo builds, wouldn't checking only for Debug build cover all the code since -DCMAKE_BUILD_TYPE=Debug is equivalent to a superset of both RelWithDebInfo and Release options from a compile time static analysis is concerned?

@VarunNagaraju
Copy link
Contributor Author

VarunNagaraju commented Jan 5, 2024

After integration, the clang-tidy warnings will be shown as review comments like VarunNagaraju#4. In any case, one can also choose to ignore addressing the comments and the push/merge option will NOT be disabled.

The comments will be posted only for the snippets of the code which are modified by the PR. But, clang-tidy will be run for the whole file(on all the files modified by the PR) and the clang-tidy log for that can be found in the Checks section or by clicking on the Show all checks > Static analysis > Details > Analyze in the workflow.

curl -sSL "http://apt.llvm.org/llvm-snapshot.gpg.key" | sudo -E apt-key add -
echo "deb http://apt.llvm.org/${UBUNTU_CODE_NAME}/ llvm-toolchain-${UBUNTU_CODE_NAME}-${COMPILER_VERSION} main" | sudo tee -a /etc/apt/sources.list > /dev/null
sudo apt-get update
sudo apt-get install -y clang-17 clang-tidy libldap2-dev curl libcurl4-openssl-dev bison libudev-dev libkrb5-dev libreadline-dev zlib1g-dev liblz4-dev \
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
sudo apt-get install -y clang-17 clang-tidy libldap2-dev curl libcurl4-openssl-dev bison libudev-dev libkrb5-dev libreadline-dev zlib1g-dev liblz4-dev \
sudo apt-get install -y clang-${COMPILER_VERSION} clang-tidy libldap2-dev curl libcurl4-openssl-dev bison libudev-dev libkrb5-dev libreadline-dev zlib1g-dev liblz4-dev \

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

- name: Prepare compile_commands.json
run: |
cmake -B ../debug-build -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_BUILD_TYPE=Debug -DDOWNLOAD_BOOST=ON -DWITH_BOOST=~/my_boost \
-DWITH_SSL=system -DWITH_AUTHENTICATION_LDAP=0 -WITH_KEYRING_VAULT=ON -DWITH_ROCKSDB=0 -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 \
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
-DWITH_SSL=system -DWITH_AUTHENTICATION_LDAP=0 -WITH_KEYRING_VAULT=ON -DWITH_ROCKSDB=0 -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 \
-DWITH_SSL=system -DWITH_AUTHENTICATION_LDAP=0 -WITH_KEYRING_VAULT=ON -DWITH_ROCKSDB=0 -DCMAKE_C_COMPILER=clang-${COMPILER_VERSION} -DCMAKE_CXX_COMPILER=clang++-${COMPILER_VERSION} \

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why -DWITH_AUTHENTICATION_LDAP=0 and -DWITH_ROCKSDB=0?
This is out code which, I believe, should also be covered.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Re, having clang-tidy checks for both Debug and RelWithDebInfo configurations. This comes just from personal experience - I remember warnings shown only in RelWithDebInfo configuration (mostly related to assert() or assert-like macros like ut_ad()). But this can definitely be a second iteration of this improvement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.
Agree.

continue-on-error: true
run: |
git diff --name-only --diff-filter=ACRM "$(git merge-base HEAD "upstream/${{ github.event.pull_request.base.ref }}")" | \
grep -Ee "\.([ch](pp)|(cc|hh)|[i](c|h)|(cxx)|[chi])$" | xargs clang-tidy -p ../debug-build --checks=-readability-* -export-fixes clang-tidy-result/fixes.yml
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure if it is suitable here but there is a standard clang-tidy-diff-17.py script coming from the clang packages. Please also check if it can be used here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I had used clang-tidy directly since it also reported warnings in unchanged sections of the code as well. But, this script will do as well. Will update it.


- name: Fetch base branch
run: |
git remote add upstream "https://github.com/${{ github.event.pull_request.base.repo.full_name }}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it OK in git to have 2 remotes pointing to the same repo?
In case we are creating a non-crossfork PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. It is unnecessary to point 2 remotes to the same repo since origin will already be pointing to the appropriate repo. Will remove it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, @VarunNagaraju I might have mislead you. I wanted to say that in case of a cross-fork PR we will need 2 remotes:

origin https://github.com/percona/percona-server.git 
fork origin https://github.com/<percona_user>/percona-server.git 

But in case of a PR within the same repo (say, when we merge release-8.0.xx-yy branch into 8.0 trunk) we will basically have

origin https://github.com/percona/percona-server.git 
fork https://github.com/percona/percona-server.git 

And my question was more about if git itself allows to have 2 remotes with different names pointing to the same repo.

curl -sSL "http://apt.llvm.org/llvm-snapshot.gpg.key" | sudo -E apt-key add -
echo "deb http://apt.llvm.org/${UBUNTU_CODE_NAME}/ llvm-toolchain-${UBUNTU_CODE_NAME}-${COMPILER_VERSION} main" | sudo tee -a /etc/apt/sources.list > /dev/null
sudo apt-get update
sudo apt-get install -y clang-${COMPILER_VERSION} clang-tidy-${COMPILER_VERSION} libldap2-dev curl libcurl4-openssl-dev bison libudev-dev libkrb5-dev libreadline-dev zlib1g-dev liblz4-dev \
Copy link
Collaborator

Choose a reason for hiding this comment

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

We may add --allow-unauthenticated here. Without this we may sporadically have issues when packages are updated or can't be authenticated (at least we had these issues with Travis CI or Azure Pipelines).
Moreover using --no-install-recommends should make install slightly faster but it will require to manually add dependencies; probably llvm-$(COMPILER_VERSION)-dev will be needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@VarunNagaraju
Copy link
Contributor Author

All the review comments are addressed and cross fork testing #5241 works as well. But, there is an issue with permissions to post comments which has popped up recently.
A ticket with the clang-tidy-pr-comments github actions has been reported platisd/clang-tidy-pr-comments#75.

@VarunNagaraju
Copy link
Contributor Author

Copy link
Collaborator

@percona-ysorokin percona-ysorokin left a comment

Choose a reason for hiding this comment

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

LGTM with minor mostly stylistic comments

.github/workflows/clang-tidy.yml Outdated Show resolved Hide resolved
.github/workflows/clang-tidy.yml Outdated Show resolved Hide resolved
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it OK to end the last element with a comma?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since, the code snippet is a javascript method invocation, the trailing comma is not a problem.
In JavaScript, it's a common practice to use trailing commas in multi-line object and array literals, mainly because it allows for cleaner git diffs when adding or removing items.

owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: "zip",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Likewise

const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Likewise

owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: "zip",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Likewise

https://perconadev.atlassian.net/browse/PS-9040

Creates a workflow to be triggered on a pull request
to perform clang-tidy checks on the changed code and post
the violations as comments on the pull request to be
addressed.

The workflow triggers a run of generating comiplation commands
and uses the same to perform a clang-tidy check on the modified
files and generates a report of the warnings in the changed code
through a github action bot in the form of review comments on
the pull request.
Copy link
Collaborator

@percona-ysorokin percona-ysorokin left a comment

Choose a reason for hiding this comment

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

LGTM

@VarunNagaraju VarunNagaraju merged commit b5dfcb2 into percona:8.0 Mar 14, 2024
25 checks passed
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.

3 participants