1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
---
name: Python Code Quality
on:
push:
branches:
- main
- releasebranch_*
pull_request:
jobs:
python-checks:
name: Python Code Quality Checks
concurrency:
group: ${{ github.workflow }}-${{ github.job }}-${{
github.event_name == 'pull_request' &&
github.head_ref || github.sha }}
cancel-in-progress: true
strategy:
matrix:
include:
- os: ubuntu-22.04
env:
# renovate: datasource=python-version depName=python
PYTHON_VERSION: "3.10"
MIN_PYTHON_VERSION: "3.8"
# renovate: datasource=pypi depName=black
BLACK_VERSION: "24.4.0"
# renovate: datasource=pypi depName=flake8
FLAKE8_VERSION: "3.9.2"
# renovate: datasource=pypi depName=pylint
PYLINT_VERSION: "2.12.2"
# renovate: datasource=pypi depName=bandit
BANDIT_VERSION: "1.7.8"
runs-on: ${{ matrix.os }}
permissions:
security-events: write
steps:
- name: Versions
run: |
echo OS: ${{ matrix.os }}
echo Python: ${{ env.PYTHON_VERSION }}
echo Minimal Python version: ${{ env.MIN_PYTHON_VERSION }}
echo Black: ${{ env.BLACK_VERSION }}
echo Flake8: ${{ env.FLAKE8_VERSION }}
echo Pylint: ${{ env.PYLINT_VERSION }}
echo Bandit: ${{ env.BANDIT_VERSION }}
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Set up Python
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: pip
- name: Upgrade pip
run: python -m pip install --upgrade pip
- name: Install Black only
run: pip install black[jupyter]==${{ env.BLACK_VERSION }}
- name: Run Black
run: black .
- name: Create and uploads code suggestions to apply for Black
# Will fail fast here if there are changes required
id: diff-black
uses: ./.github/actions/create-upload-suggestions
with:
tool-name: black
# To keep repo's file structure in formatted changes artifact
extra-upload-changes: .clang-format
- name: Install non-Python dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y wget git gawk findutils
xargs -a <(awk '! /^ *(#|$)/' ".github/workflows/apt.txt") -r -- \
sudo apt-get install -y --no-install-recommends --no-install-suggests
- name: Install Python dependencies
run: |
pip install -r .github/workflows/python_requirements.txt
pip install -r .github/workflows/optional_requirements.txt
pip install flake8==${{ env.FLAKE8_VERSION }}
pip install pylint==${{ env.PYLINT_VERSION }} pytest-github-actions-annotate-failures
pip install bandit[sarif]==${{ env.BANDIT_VERSION }}
- name: Run Flake8
run: |
flake8 --count --statistics --show-source --jobs=$(nproc) .
- name: Run Flake8 on additional files
run: |
flake8 --count --statistics --show-source --jobs=$(nproc) python/grass/{script,jupyter}/testsuite/
- name: Bandit Vulnerability Scan
run: |
bandit -c pyproject.toml -iii -r . -f sarif -o bandit.sarif --exit-zero
- name: Upload Bandit Scan Results
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: bandit.sarif
path: bandit.sarif
- name: Upload SARIF File into Security Tab
uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10
with:
sarif_file: bandit.sarif
- name: Create installation directory
run: |
mkdir $HOME/install
- name: Set number of cores for compilation
run: |
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
- uses: rui314/setup-mold@8de9eea54963d01c1a6c200606257d65bd53bea1 # v1
- name: Build
run: .github/workflows/build_${{ matrix.os }}.sh $HOME/install
- name: Add the bin directory to PATH
run: |
echo "$HOME/install/bin" >> $GITHUB_PATH
- name: Run Pylint on grass package
run: |
export PYTHONPATH=`grass --config python_path`:$PYTHONPATH
export LD_LIBRARY_PATH=$HOME/install/grass84/lib:$LD_LIBRARY_PATH
cd python
pylint --persistent=no --py-version=${{ env.MIN_PYTHON_VERSION }} --jobs=$(nproc) grass
- name: Run Pylint on wxGUI
run: |
export PYTHONPATH=`grass --config python_path`:$PYTHONPATH
export LD_LIBRARY_PATH=$HOME/install/grass84/lib:$LD_LIBRARY_PATH
cd gui/wxpython
pylint --persistent=no --py-version=${{ env.MIN_PYTHON_VERSION }} --jobs=$(nproc) *
- name: Run Pylint on other files using pytest
run: |
pip install pytest==7.4.4 pytest-pylint==0.19
echo "::warning file=.github/workflows/python-code-quality.yml,line=149,col=42,endColumn=48::\
Temporarily downgraded pytest-pylint and pytest to allow merging other PRs.\
The errors reported with a newer version seem legitimite and should be fixed \
(2023-10-18, see https://github.com/OSGeo/grass/pull/3205)\
(2024-01-28, see https://github.com/OSGeo/grass/issues/3380)"
export PYTHONPATH=`grass --config python_path`:$PYTHONPATH
export LD_LIBRARY_PATH=$HOME/install/grass84/lib:$LD_LIBRARY_PATH
pytest --pylint -m pylint --pylint-rcfile=.pylintrc --pylint-jobs=$(nproc) \
--pylint-ignore-patterns="${{ env.PylintIgnore }}"
env:
PylintIgnore: "python/.*,gui/wxpython/.*,doc/.*,man/.*,utils/.*,locale/.*,raster/.*,\
imagery/.*,scripts/r.in.wms/wms_drv.py,scripts/g.extension/g.extension.py,\
temporal/t.rast.accdetect/t.rast.accdetect.py,temporal/t.rast.accumulate/t.rast.accumulate.py,\
scripts/d.rast.edit/d.rast.edit.py"
- name: Test compiling example modules
run: |
( cd doc/raster/r.example/ && make )
( cd doc/vector/v.example/ && make )
- name: Run Sphinx to check API documentation build
run: |
pip install sphinx
make sphinxdoclib
ARCH=$(cat include/Make/Platform.make | grep ^ARCH | cut -d'=' -f2 | xargs)
cp -rp dist.$ARCH/docs/html/libpython sphinx-grass
- name: Make Sphinx documentation available
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: sphinx-grass
path: sphinx-grass
retention-days: 3
python-success:
name: Python Code Quality Result
needs:
- python-checks
if: ${{ always() }}
uses: ./.github/workflows/verify-success.yml
with:
needs_context: ${{ toJson(needs) }}
|