I have created a GitHub actions pipeline to do linting of the recent committed code. The test script works in my local environment, but not on the GitHub server. What peculiarity I don't notice?
Here is my code for linting:
#!/usr/bin/env bash
LATEST_COMMIT=$(git rev-parse HEAD);
echo "Analyzing code changes under the commit hash: $LATEST_COMMIT";
FILES_UNDER_THE_LATEST_COMMIT=$(git diff-tree --no-commit-id --name-only -r $LATEST_COMMIT);
echo "Files under the commit:";
echo $FILES_UNDER_THE_LATEST_COMMIT;
MATCHES=$(echo $FILES_UNDER_THE_LATEST_COMMIT | grep '.py');
echo "Files under the commit with Python extension: $MATCHES";
echo "Starting linting...";
if echo $MATCHES | grep -q '.py';
then
echo $MATCHES | xargs pylint --rcfile .pylintrc;
else
echo "Nothing to lint";
fi
Here is my GitHub Actions config:
name: Pylint
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
if: "!contains(github.event.head_commit.message, 'NO_LINT')"
run: |
python -m pip install --upgrade pip
pip install pylint psycopg2 snowflake-connector-python pymssql
chmod x .github/workflows/run_linting.sh
- name: Analysing all Python scripts in the project with Pylint
if: "contains(github.event.head_commit.message, 'CHECK_ALL')"
run: pylint --rcfile .pylintrc lib processes tests
- name: Analysing the latest committed changes Pylint
if: "!contains(github.event.head_commit.message, 'NO_LINT')"
run: .github/workflows/run_linting.sh
CodePudding user response:
Here's your problem in a nutshell:
steps: - uses: actions/checkout@v3
By default, checkout@v2
and checkout@v3
make a shallow (depth 1), single-branch clone. Such a clone has exactly one commit in it: the most recent one.
As a consequence, this:
git diff-tree --no-commit-id --name-only -r $LATEST_COMMIT
produces no output at all. There's no parent commit available to compare against. (I'd argue that this is a bit of a bug in Git: git diff-tree
should notice that the parent is missing due to the .git/shallow
grafts file. However, git diff-tree
traditionally produces an empty diff for a root commit, and without special handling in git diff-tree
, the shallow clone makes git diff-tree
think this is a root commit. Oddly, the user-oriented git diff
would treat every file as added—still not what you want, but it would have actually worked.)
To fix this, force the depth to be at least 2. Using depth: 0
will force a full (non-shallow) clone, but the reason for using a shallow, single-branch clone is to speed up the action by omitting unnecessary commits. As only the first two "layers" of commit are required here, depth: 2
provides the correct number.
Side note: your bash
code has every command terminated with a semicolon. This works fine, but is unnecessary (it reminds me of doing too much C or C programming.1 Also, you can just run git diff-tree <options> HEAD
: there's no need for a separate git rev-parse
step here (though you might still want that in the echo
).
1As I switch from C to C to Go to Python to shell etc., I either put in too many or too few parentheses and semicolons, leading to C compiler errors from:
if x == 0 {
because my brain is in Go mode.