-
Notifications
You must be signed in to change notification settings - Fork 0
224 lines (213 loc) · 10.2 KB
/
pytest.yml
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# For more information on GitHub Actions for Python projects, see: https://git.io/JtENw
name: pytest
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ${{ matrix.os }}
# Uncomment this line if we are running on a solitary OS
# runs-on: ubuntu-latest
strategy:
matrix:
# Uncomment this line if we are running on multiple operating systems
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
env:
# From https://docs.astral.sh/uv/guides/integration/github/#caching
UV_CACHE_DIR: /tmp/.uv-cache
UV_SYSTEM_PYTHON: 1
steps:
- name: Get latest Git (Win) https://github.com/actions/runner-images/issues/10843
if: startsWith(runner.os, 'Windows')
run: |
git.exe --version ;
Start-Process git.exe -Wait -ArgumentList 'update-git-for-windows -y' ;
git.exe --version ;
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
# uv pip cache dependencies to save time
- name: Restore uv cache
uses: actions/cache@v4
with:
path: /tmp/.uv-cache
key: uv-${{ runner.os }}-${{ hashFiles('requirements.txt') }}
restore-keys: |
uv-${{ runner.os }}-${{ hashFiles('requirements.txt') }}
uv-${{ runner.os }}
# - name: Use deploy key
# uses: webfactory/[email protected]
# with:
# ssh-private-key: ${{ secrets.ZZBASE_TOKEN }}
- name: Install uv
shell: bash
run: python -u -m pip install --upgrade uv=="$(python -u -c 'from pathlib import Path;print(list(set([x for x in Path("pyproject.toml").read_text(encoding="utf-8").splitlines() if "uv >= " in x]))[0].split("# ", maxsplit=1)[0].strip().split("\"")[1].removeprefix("uv >= "))')"
- name: Remove subdomain to make requirements.txt setup work in CI
run: python -c 'import fileinput; [print(line.partition("git@")[0] + "[email protected]/" + line.partition(".github.com/")[-1] if (".github.com/" in line and not line.startswith("#")) else line, end="") for line in fileinput.input(inplace=True)]' requirements.txt
- name: Print differences in git repository needed to make CI work
run: git diff
- name: Install requirements from possibly-changed requirements.txt, and package in development mode
run: uv pip install -r requirements.txt -e .
- name: Revert requirements.txt if changed
run: git checkout -- requirements.txt
- name: Run with ruff
run: python -u -m ruff check .
- name: Run with refurb to find code that can be written in a more modern way
if: startsWith(runner.os, 'Linux')
run: python -u -m refurb .
- name: Run pyright
if: startsWith(runner.os, 'Linux')
run: python -u -m pyright
- name: Install OS prerequisites
if: startsWith(runner.os, 'Linux')
run: sudo apt-get update ; sudo apt-get install ripgrep
- name: Search for existing linter ignore lines in Python
if: startsWith(runner.os, 'Linux')
run: |
rg -t py --stats "(?:(?:flake8|noqa|pylint|pyright|type): *(?:disable|ignore|noqa|[a-zA-Z]+[0-9]+)| Any|REPLACEME)" \
$(find . -type f -name "*.py" -not -path "./build/lib/*" ! -name "conf_correct.py") || true
- name: Ensure we are not increasing the number of ignore lines as a guideline
if: startsWith(runner.os, 'Linux')
run: |
if [ $(rg -t py --stats \
"(?:(?:flake8|noqa|pylint|pyright|type): *(?:disable|ignore|noqa|[a-zA-Z]+[0-9]+)| Any|REPLACEME)" \
$(find . -type f -name "*.py" -not -path "./build/lib/*" ! -name "conf_correct.py") \
| awk "/ matches/ && "\!"/ contained matches/" \
| cut -d " " -f1) -lt 5 ] ;
then exit 0 ; else exit 1 ; fi ;
- name: Run shellcheck
if: startsWith(runner.os, 'Linux')
run: rg -t sh --files | xargs shellcheck
- name: Run bashate
if: startsWith(runner.os, 'Linux')
run: rg -t sh --files | xargs bashate -i E006
- name: Generate Sphinx docs (inspect this output for Sphinx errors)
if: startsWith(runner.os, 'Linux')
run: |
( pushd docs/ > /dev/null && ./gen-sphinx-html.sh 2>&1 | rg ": (ERROR|WARNING|CRITICAL): " ; popd > /dev/null ; ) || true
- name: Reset Git repo after Sphinx documentation generation
if: startsWith(runner.os, 'Linux')
run: git clean -fd
- name: Fail if Sphinx doc generation has Sphinx errors
if: startsWith(runner.os, 'Linux')
run: |
if [ "$( pushd docs/ > /dev/null && ./gen-sphinx-html.sh 2>&1 | rg ": (ERROR|WARNING|CRITICAL): " | wc -l ; popd > /dev/null ; )" != "0" ] ; then exit 1 ; fi ;
- name: Reset Git repo a second time after Sphinx documentation generation
if: startsWith(runner.os, 'Linux')
run: git clean -fd
- name: Run tools using pytest
run: |
python -u -m pytest --cov --mypy --pylint --ruff --ruff-format --vulture
# CodeQL analysis section START
# Linux-only, enable on GitHub for public repos and private repos on Enterprise plan with Advanced Security
# IMPORTANT setup steps:
# 1) If this is a private repo NOT on a GitHub Enterprise plan with Advanced Security, disable the last CodeQL result upload step
# 2) Check ${{ secrets.CODEQL_UPLOAD_TOKEN }} has been added and updated in the GitHub settings of this repo
# 3) Check CodeQL languages for this repo are updated correctly
- name: CodeQL languages, comma-separated, for list see https://codeql.github.com/docs/codeql-cli/creating-codeql-databases/
if: startsWith(runner.os, 'Linux')
run: echo "CODEQL_LANGUAGES=python," >> "$GITHUB_ENV"
# CodeQL preprocessing checks commence
- name: Current git branch ref
if: startsWith(runner.os, 'Linux')
run: echo "$GITHUB_REF"
- name: Current git commit
if: startsWith(runner.os, 'Linux')
run: echo $(git rev-parse --verify HEAD)
- name: Current repository name
if: startsWith(runner.os, 'Linux')
run: echo "$GITHUB_REPOSITORY"
- name: Find CodeQL files on GitHub Actions runner OS
if: startsWith(runner.os, 'Linux')
run: pushd /opt/hostedtoolcache/CodeQL/ || exit ; export CODEQL_VER=( * ) ; echo CODEQL_DIR="/opt/hostedtoolcache/CodeQL/${CODEQL_VER[-1]}/x64/codeql" >> "$GITHUB_ENV" ; popd || exit ;
- name: Find CodeQL binary on GitHub Actions runner OS
if: startsWith(runner.os, 'Linux')
run: |
if [ -f $(echo "$CODEQL_DIR"/codeql) ] ;
then
echo CODEQL_BIN=$(echo "$CODEQL_DIR"/codeql) >> "$GITHUB_ENV" ;
else
exit 1 ;
fi ;
- name: Get the codeql version
if: startsWith(runner.os, 'Linux')
run: |
"$CODEQL_BIN" --version
- name: Check that the qlpacks exist for specified languages
if: startsWith(runner.os, 'Linux')
run: |
for LANG in $(echo "$CODEQL_LANGUAGES" | tr "," " ") ;
do
if ! "$CODEQL_BIN" resolve qlpacks | grep -q "$LANG-" ;
then
exit 1 ;
fi ;
done ;
- name: Check that the codeql queries exist for specified languages
if: startsWith(runner.os, 'Linux')
run: |
for LANG in $(echo "$CODEQL_LANGUAGES" | tr "," " ") ;
do
if ! ls "$CODEQL_DIR"/qlpacks/codeql/"$LANG"-queries/*.*/codeql-suites/ | grep -q "$LANG-" ;
then
exit 1 ;
fi ;
done ;
# CodeQL preprocessing checks finish
- name: Create codeql database for specified languages
if: startsWith(runner.os, 'Linux')
run: |
"$CODEQL_BIN" database create codeql-result-database/ --db-cluster --language="$CODEQL_LANGUAGES" ;
- name: Run codeql analysis on each specified languages
if: startsWith(runner.os, 'Linux')
run: |
for LANG in $(echo "$CODEQL_LANGUAGES" | tr "," " ") ;
do
"$CODEQL_BIN" database analyze codeql-result-database/"$LANG"/ --sarif-category="$LANG" --output=out-"$LANG".sarif --format=sarif-latest --threads=0 ;
done ;
- name: Upload codeql results to public GitHub repo or private repo on an enterprise plan with Advanced Security
if: startsWith(runner.os, 'Linux')
run: |
echo "$CODEQL_TOKEN" |
for SARIF in $(ls out-*.sarif) ;
do
"$CODEQL_BIN" github upload-results --commit=$(git rev-parse --verify HEAD) --ref="$GITHUB_REF" --repository="$GITHUB_REPOSITORY" --sarif="$SARIF" --github-auth-stdin ;
done ;
env:
CODEQL_TOKEN: ${{ secrets.CODEQL_UPLOAD_TOKEN }}
# We should search through grep after trying to upload, if applicable
# grep returns exit code 1 if string is not found but specified file is present
# grep returns exit code 2 if specified file is not present
- name: Look for startLine to see if any issues are found, if so, return exit code 1
if: startsWith(runner.os, 'Linux')
run: |
for OUT_FILE in $(ls out-*.sarif) ;
do
if ! (
grep --context=11 startLine "$OUT_FILE" ;
EXIT_CODE=$? ;
if [ "$EXIT_CODE" -eq 0 ] ;
then
exit 1;
fi ;
) ;
then
exit 1 ;
fi ;
done ;
# CodeQL analysis section END
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
continue-on-error: true # codecov limits number of uploads allowed for each commit
with:
env_vars: OS,PYTHON
fail_ci_if_error: true # optional (default = false)
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
- name: Minimize uv cache, --ci will only keep locally-built packages
run: uv cache prune --ci