On 2 Jan 2024, at 13:43, Ilya Maximets wrote:
> On 12/20/23 16:07, Eelco Chaudron wrote: >> >> >> On 20 Dec 2023, at 11:19, Eelco Chaudron wrote: >> >>> This patch identifies new static analysis issues during a GitHub action >>> run and reports them. The process involves analyzing the changes introduced >>> in the current commit and comparing them to those in the preceding commit. >>> >>> However, there are two cases when the GitHub push action runner does not >>> provide enough details to determen the preceding commit. These cases are >>> a new branch or a forced push. The strategy for these exceptions is to >>> select the first commit not done by the current author as the base commit. >> >> Including Aarons comment on v3 into v4. >> >> +++ As an alternative we can look at the author (go back in time until >> +++ we find a different author), so if you’re lucky and it’s one of your >> +++ older patches you will be reminded again and again ;) Not sure if >> +++ this is easaly possible with a git command, but it might be worth >> +++ trying out. >> >> ++ I did some experiments with the above approach, and it seems to work >> ++ in all the use cases. The only problem could be that if you are also >> ++ the owner of a previous patch series, it might use a reference branch >> ++ too deep. This could potentially show issues not introduced by your >> ++ latest patches. But as you are still the author, you should be >> ++ “punished” for your earlier mistakes ;) >> ++ >> ++ I’ll send out a v4, and we can continue the discussion there if needed :) >> >> + I'll take a look after Jan 1, but I guess we might be able to check >> + against an upstream reference (for example, we can reference towards the >> + 'upstream' repository - such a reference does require some kind of >> + history being pulled) which we know should be stable and 'good'. IE: >> + the script could add the OVS github remote if it doesn't already exist. >> + I think we could use that to find the common ancestor. But I need to >> + dive into this more. >> >> I guess we can determine the origin branch going back, and then do something >> like >> `git merge-base upstream/master HEAD` assuming we fetched the upstream >> repository. > > > The 'determine the origin branch' is still tricky and requires some > guesswork in case of a new branch or a force push. Maybe something > like listing all the heads in upstream repo and finding the one that > has the closest merge-base may be an option. Then use that merge base > as a base commit to compare against. > > The merge-base with upstream/master will be a branching point for a > release branch, and that is way too far. ACK, I think going back in time till a different author will solve all this for now. And this will even work in Ilya’s and my force commit workflow. So for now I’ll keep it as it. >> >> Both solutions will work, and I have no real preference. >> >> //Eelco >> >>> An example error output might look like this: >>> >>> error level: +0 -0 no changes >>> warning level: +2 +0 >>> New issue "deadcode.DeadStores Value stored to 'remote' is never read" >>> (1 occurrence) >>> file:///home/runner/work/ovs/ovs/vswitchd/ovs-vswitchd.c:86 >>> New issue "unix.Malloc Potential leak of memory pointed to by 'remote'" >>> (1 occurrence) >>> file:///home/runner/work/ovs/ovs/vswitchd/ovs-vswitchd.c:95 >>> note level: +0 -0 no changes >>> all levels: +2 +0 >>> >>> Signed-off-by: Eelco Chaudron <echau...@redhat.com> >>> --- >>> >>> changes in v2: >>> - When it's a new branch, it compares it to the HEAD of the default >>> branch. >>> >>> changes in v3: >>> - Include the clang version as part of the cache >>> - Change the way it looks for the 'default' branch so it will work >>> for patch branches. >>> - Also compare to the base branch for forced commits. >>> >>> changes in v4: >>> - No longer look for a default branch, but consume all patches >>> from the current author. >>> >>> .ci/linux-build.sh | 29 ++++++++++ >>> .github/workflows/build-and-test.yml | 103 >>> ++++++++++++++++++++++++++++++++++ >>> 2 files changed, 132 insertions(+) >>> >>> diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh >>> index aa2ecc505..fedf1398a 100755 >>> --- a/.ci/linux-build.sh >>> +++ b/.ci/linux-build.sh >>> @@ -49,6 +49,30 @@ function build_ovs() >>> make -j4 >>> } >>> >>> +function clang_analyze() >>> +{ >>> + [ -d "./base-clang-analyzer-results" ] && cache_build=false \ >>> + || cache_build=true >>> + if [ "$cache_build" = true ]; then >>> + # If this is a cache build, proceed to the base branch's directory. >>> + cd base_ovs_main > > pushd/popd might be better here. ACK will do this next revision. > >>> + fi; >>> + >>> + configure_ovs $OPTS >>> + make clean >>> + scan-build -o ./clang-analyzer-results -sarif --use-cc=clang make -j4 > > We have a make target for clang-analyze and it depends on the clean already. > Maybe we can extend it to accept custom arguments via env variable and pass > the '-sarif' this way? E.g. make clang-analyze SCAN_BUILD_OPTIONS="-sarif". Let me look into this, as I like the idea. > Also, -j4 should be changed to ${JOBS} since that patch got merged. ACK > And we have CC defined in the job description, so should not use clang > directly. ACK >>> + >>> + if [ "$cache_build" = true ]; then >>> + # Move results, so it will be picked up by the cache. >>> + mv ./clang-analyzer-results ../base-clang-analyzer-results >>> + cd .. >>> + else >>> + # Only do the compare on the none cache builds. >>> + sarif --check note diff ./base-clang-analyzer-results \ >>> + ./clang-analyzer-results >>> + fi; >>> +} >>> + >>> if [ "$DEB_PACKAGE" ]; then >>> ./boot.sh && ./configure --with-dpdk=$DPDK && make debian >>> mk-build-deps --install --root-cmd sudo --remove debian/control >>> @@ -116,6 +140,11 @@ fi >>> >>> OPTS="${EXTRA_OPTS} ${OPTS} $*" >>> >>> +if [ "$CLANG_ANALYZE" ]; then >>> + clang_analyze >>> + exit 0 >>> +fi >>> + >>> if [ "$TESTSUITE" = 'test' ]; then >>> # 'distcheck' will reconfigure with required options. >>> # Now we only need to prepare the Makefile without sparse-wrapped CC. >>> diff --git a/.github/workflows/build-and-test.yml >>> b/.github/workflows/build-and-test.yml >>> index 09654205e..cb277ff43 100644 >>> --- a/.github/workflows/build-and-test.yml >>> +++ b/.github/workflows/build-and-test.yml >>> @@ -223,6 +223,109 @@ jobs: >>> name: logs-linux-${{ join(matrix.*, '-') }} >>> path: logs.tgz >>> >>> + build-clang-analyze: >>> + needs: build-dpdk >>> + env: >>> + dependencies: | >>> + automake bc clang-tools libbpf-dev libnuma-dev libpcap-dev \ >>> + libunbound-dev libunwind-dev libssl-dev libtool llvm-dev \ >>> + python3-unbound > > Do we need a python3-unbound? Added it, as I removed the 32-bit conditional install, but can verify if it fails without. >>> + CC: clang >>> + DPDK: dpdk >>> + CLANG_ANALYZE: true >>> + name: clang-analyze >>> + runs-on: ubuntu-22.04 >>> + timeout-minutes: 30 >>> + >>> + steps: >>> + - name: checkout >>> + uses: actions/checkout@v3 >>> + with: >>> + fetch-depth: 0 >>> + >>> + - name: get base branch sha >>> + id: base_branch >>> + env: >>> + BASE_SHA: ${{ github.event.pull_request.base.sha }} >>> + EVENT_BEFORE: ${{ github.event.before }} >>> + FORCED_PUSH: ${{ github.event.forced }} >>> + run: | >>> + if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then >>> + echo "sha=$BASE_SHA" >> $GITHUB_OUTPUT >>> + else >>> + if [ "$EVENT_BEFORE" = >>> "0000000000000000000000000000000000000000" ] \ >>> + || [ "$FORCED_PUSH" = true ]; then >>> + echo "sha=$(git log --pretty=format:"%H %ae" | \ >>> + grep -m1 -v $(git log -1 --pretty=format:"%ae") | \ >>> + awk '{print $1}')" >> $GITHUB_OUTPUT >>> + else >>> + echo "sha=$EVENT_BEFORE" >> $GITHUB_OUTPUT >>> + fi >>> + fi >>> + >>> + - name: checkout base branch >>> + uses: actions/checkout@v3 >>> + with: >>> + ref: ${{ steps.base_branch.outputs.sha }} >>> + path: base_ovs_main >>> + >>> + - name: update PATH >>> + run: | >>> + echo "$HOME/bin" >> $GITHUB_PATH >>> + echo "$HOME/.local/bin" >> $GITHUB_PATH >>> + >>> + - name: generate cache key >>> + id: cache_key >>> + run: | >>> + ver=$(clang -v 2>&1 | grep version | \ > > s/clang/${CC}/ ? > > And if we grep for ' version ', the check will work for gcc as well, > even if we do not really care about this case. :) ACK, will make the change below as well. >>> + sed 's/.*version \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/g') >>> + echo "key=clang-${ver}-analyze-$(git -C base_ovs_main rev-parse >>> HEAD)" \ >>> + >> $GITHUB_OUTPUT >>> + >>> + - name: check for analyzer result cache >>> + id: clang_cache >>> + uses: actions/cache@v3 >>> + with: >>> + path: base-clang-analyzer-results >>> + key: ${{ steps.cache_key.outputs.key }} >>> + >>> + - name: set up python >>> + uses: actions/setup-python@v4 >>> + with: >>> + python-version: '3.9' >>> + >>> + - name: get cached dpdk-dir >>> + uses: actions/cache/restore@v3 >>> + with: >>> + path: dpdk-dir >>> + key: ${{ needs.build-dpdk.outputs.dpdk_key }} >>> + >>> + - name: update APT cache >>> + run: sudo apt update || true >>> + >>> + - name: install common dependencies >>> + run: sudo apt install -y ${{ env.dependencies }} >>> + >>> + - name: install sarif tools >>> + run: sudo pip3 install --disable-pip-version-check sarif-tools > > '--user' to avoid sudo. Might also be better to add this to the > existing command in the linux-prepare script instead to allow pip > to choose compatible versions of all the packages. Let me move it to see if this will work. >>> + >>> + - name: prepare >>> + run: ./.ci/linux-prepare.sh >>> + >>> + - name: build base reference >>> + if: steps.clang_cache.outputs.cache-hit != 'true' >>> + run: ./.ci/linux-build.sh >>> + >>> + - name: build >>> + run: ./.ci/linux-build.sh >>> + >>> + - name: save cache >>> + uses: actions/cache/save@v3 >>> + if: always() && steps.clang_cache.outputs.cache-hit != 'true' > > So, we will save the cache even if the build of the base reference failed? > Maybe move this before the 'build' stage and remove the 'always()' check? Good catch, will move it up. >>> + with: >>> + path: base-clang-analyzer-results >>> + key: ${{ steps.cache_key.outputs.key }} >>> + >>> build-osx: >>> env: >>> CC: clang >>> > > Best regards, Ilya Maximets. Thanks for the comments, will prep a v5. //Eelco _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev