From ea76703e36acad194f81b06791af97a831d2d0a4 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Thu, 4 Mar 2021 19:21:22 +0000 Subject: [PATCH] .github: add shallow checkpatch to Github Actions Let's try to run checkpatch in an open-source and fast way while leveraging Github's very good user interface. Run checkpatch both with and without --strict; this has been a source of confusion in the past, see https://github.com/thesofproject/linux/pull/1988 Note this attempt does not rely on git merge-bases which has been found to be not compatible with shallow cloning: https://github.com/thesofproject/linux/issues/2556 Signed-off-by: Marc Herbert --- .github/workflows/shallow_checkpatch.yml | 55 +++++++++++++++++ .github/workflows/shallowfetchPRcommits.sh | 69 ++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 .github/workflows/shallow_checkpatch.yml create mode 100755 .github/workflows/shallowfetchPRcommits.sh diff --git a/.github/workflows/shallow_checkpatch.yml b/.github/workflows/shallow_checkpatch.yml new file mode 100644 index 000000000000..9cf424f8cfe8 --- /dev/null +++ b/.github/workflows/shallow_checkpatch.yml @@ -0,0 +1,55 @@ +--- +# SPDX-License-Identifier: BSD-3-Clause +# Tools that can save round-trips to github and a lot of time: +# +# yamllint -f parsable this.yml +# pip3 install ruamel.yaml.cmd +# yaml merge-expand this.yml exp.yml && diff -w -u this.yml exp.yml +# +# github.com also has a powerful web editor that can be used without +# committing. + +name: checkpatch + +# yamllint disable-line rule:truthy +on: [pull_request] + +jobs: + checkpatch: + runs-on: ubuntu-20.04 + env: + PR_NUM: ${{github.event.number}} + CHK_CMD: ./scripts/checkpatch.pl --codespell --codespellfile + /usr/lib/python3/dist-packages/codespell_lib/data/dictionary.txt + steps: + # depth 2 so: + # ^1. we can show the Subject of the current target branch tip + # ^2. we reconnect/graft to the later fetch pull/1234/head, + - uses: actions/checkout@v2 + with: {fetch-depth: 2} + + - name: yamllint ourselves + run: yamllint .github/workflows/shallow_checkpatch.yml + + - name: install codespell + run: sudo apt-get -y install codespell && dpkg -L codespell | grep dict + + # See shallowness issue https://github.com/thesofproject/linux/issues/2556 + - name: fetch PR commits + run: | + .github/workflows/shallowfetchPRcommits.sh \ + ${GITHUB_REPOSITORY} "$PR_NUM" + # show what we got + git --no-pager log --oneline --graph --decorate --max-count=50 + + - name: checkpatch + run: while read -r sha ; do + printf '\n -------------- \n\n'; + ${CHK_CMD} -g $sha; + done < PR_SHAs.txt + + - name: checkpatch --strict + run: while read -r sha ; do + printf '\n -------------- \n\n'; + ${CHK_CMD} --strict -g $sha; + done < PR_SHAs.txt diff --git a/.github/workflows/shallowfetchPRcommits.sh b/.github/workflows/shallowfetchPRcommits.sh new file mode 100755 index 000000000000..6330a328403e --- /dev/null +++ b/.github/workflows/shallowfetchPRcommits.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# SPDX-License-Identifier: BSD-3-Clause + +set -e + +# This script fetches Pull Request commits missing from a shallow clone +# and creates a PR_SHAs.txt file. This script has a limit of 500 commits but the +# github API used has a lower limit of 250 commits. + +# It does not rely on git merge-bases which basically don't work with +# shallow clones: +# https://github.com/thesofproject/linux/issues/2556 + +# Design goals: +# +# - Keep the code short and as simple as possible. No one is interested +# in maintaining this sort of script. +# +# - Fast and accurate for small Pull Requests +# +# - For large Pull Requests _with merges_ the only objective is to +# complete in a reasonable time; say less than 10 minutes. It's very +# unlikely will look at 250 checkpatch results and time optimizations +# should not make this script more complex. + + +# Sample usage: +# $0 thesoftproject/linux 2772 +main() +{ + local gh_project="$1" + local pr_number="$2" + + printf '%s: fetching PR %d for project %s\n' "$0" "$pr_number" "$gh_project" + + # As of March 2021, Github's documented limit is 250 commits + # Let's have another cap a 500. + # https://docs.github.com/en/rest/reference/pulls#list-commits-on-a-pull-request + local pagelen PRlen=0 + for i in 1 2 3 4 5; do + curl -H 'Accept: application/vnd.github.v3+json' \ + "https://api.github.com/repos/$gh_project/pulls/$pr_number/commits?per_page=100&page=$i" \ + > commits_"$i".json + pagelen=$(jq length < commits_$i.json) + if [ "$pagelen" -eq 0 ]; then + break + fi + PRlen=$((PRlen + pagelen)) + done + + printf 'Found %d commits, SHA1 list is in PR_SHAs.txt\n' "$PRlen" + + # 'cut' removes double quotes + cat commits_?.json | + jq '.[] | .sha' | + cut -b2-41 > PR_SHAs.txt + + # PRlen+1 gets us the merge base for simple, linear histories. For + # pull requests with merges, depth=PRLEN goes already much further + # than needed and +1 makes little difference. It's not clear when + # and for what sort of PRs git fetching individual commits would be + # faster so keep a single and simple fetch for now. + + set -x # this command may take a while so show it + git fetch --depth "$((PRlen+1))" "http://github.com/$gh_project" "pull/$pr_number/head" + +} + +main "$@"