1111 - " interactive_mode.py"
1212 - " test_run.py"
1313 - " requirements.txt"
14+ - " tests/**"
1415 - " .github/workflows/**"
1516 pull_request :
1617 branches :
2223 - " interactive_mode.py"
2324 - " test_run.py"
2425 - " requirements.txt"
26+ - " tests/**"
2527 - " .github/workflows/**"
2628 schedule :
27- - cron : " 0 0 * * 0" # Run weekly on Sundays
28- workflow_dispatch : # Allow manual triggering
29+ - cron : " 0 0 * * 0" # Weekly on Sundays
30+ workflow_dispatch :
2931
3032jobs :
3133 lint :
@@ -39,54 +41,92 @@ jobs:
3941 uses : actions/setup-python@v5
4042 with :
4143 python-version : " 3.10"
42- cache : " pip" # Enable pip caching
44+ cache : " pip"
4345
4446 - name : Install dependencies
4547 run : |
4648 python -m pip install --upgrade pip
4749 pip install flake8 black isort pylint
48- if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
50+ pip install -r requirements.txt
51+
52+ # Set up .pylintrc if it doesn't exist
53+ - name : Configure Pylint
54+ run : |
55+ if [ ! -f .pylintrc ]; then
56+ echo "[MASTER]
57+ init-hook='import sys; sys.path.append(\".\")'
58+
59+ [MESSAGES CONTROL]
60+ disable=C0111,C0103,C0303,C0330,C0326,W0511,R0903,R0913,R0914,R0912,R0915,R0902,R0801,W0212,W0703,C0111,C0103,C0303,C0330,C0326
61+
62+ [FORMAT]
63+ max-line-length=127" > .pylintrc
64+ fi
4965
5066 - name : Check formatting with Black
51- run : black --check Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py
67+ id : black
68+ run : |
69+ black --check --diff .
5270 continue-on-error : true
5371
72+ - name : Fix formatting with Black if check fails
73+ if : steps.black.outcome == 'failure'
74+ run : |
75+ black .
76+ git config --global user.name "GitHub Actions"
77+ git config --global user.email "actions@github.com"
78+ git add .
79+ git commit -m "Fix code formatting with Black" || echo "No changes to commit"
80+
5481 - name : Check imports with isort
55- run : isort --check-only --profile black Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py
82+ id : isort
83+ run : |
84+ isort --check-only --profile black .
5685 continue-on-error : true
5786
87+ - name : Fix imports with isort if check fails
88+ if : steps.isort.outcome == 'failure'
89+ run : |
90+ isort --profile black .
91+ git config --global user.name "GitHub Actions"
92+ git config --global user.email "actions@github.com"
93+ git add .
94+ git commit -m "Fix imports with isort" || echo "No changes to commit"
95+
5896 - name : Lint with flake8
5997 run : |
6098 # Stop the build if there are Python syntax errors or undefined names
61- flake8 Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py --count --select=E9,F63,F7,F82 --show-source --statistics
62- # Exit-zero treats all errors as warnings
63- flake8 Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
99+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
100+ # Full check with exit-zero treats all errors as warnings
101+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
102+ continue-on-error : true
64103
65- - name : Check with pylint
104+ - name : Run pylint
66105 run : |
67- pylint --disable=all --enable=unused-import,unused-variable,unused-argument,undefined-variable Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py
106+ pylint --recursive=y --output-format=colorized . || echo "Pylint completed with warnings/errors"
68107 continue-on-error : true
69108
70- - name : Generate linting reports
109+ - name : Generate code quality reports
71110 run : |
72111 mkdir -p reports
73- flake8 Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py --output-file=reports/flake8.txt
74- pylint Snatch.py setup.py setup_ffmpeg.py interactive_mode.py test_run.py -f json > reports/pylint.json || true
112+ flake8 . --output-file=reports/flake8.txt --exit-zero
113+ pylint --recursive=y . -f json > reports/pylint.json || true
75114
76- - name : Upload linting reports
115+ - name : Upload code quality reports
77116 uses : actions/upload-artifact@v4
78117 with :
79- name : linting -reports
118+ name : code-quality -reports
80119 path : reports/
120+ retention-days : 14
81121
82122 test :
83- name : Test
123+ name : Test on ${{ matrix.os }} with Python ${{ matrix.python-version }}
84124 runs-on : ${{ matrix.os }}
85125 needs : lint
86126 strategy :
87127 matrix :
88128 os : [ubuntu-latest, windows-latest]
89- python-version : ["3.8", "3.9", "3. 10", "3.11"]
129+ python-version : ["3.8", "3.10", "3.11"]
90130 fail-fast : false
91131
92132 steps :
@@ -102,8 +142,8 @@ jobs:
102142 - name : Install dependencies
103143 run : |
104144 python -m pip install --upgrade pip
105- pip install pytest pytest-cov
106- if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
145+ pip install pytest pytest-cov pytest-xdist pytest-html
146+ pip install -r requirements.txt
107147 shell : bash
108148
109149 - name : Install FFmpeg (Ubuntu)
@@ -116,35 +156,53 @@ jobs:
116156 if : matrix.os == 'windows-latest'
117157 run : |
118158 choco install ffmpeg -y
159+ # Fix potential PATH issues
160+ echo "$env:ProgramData\chocolatey\bin" | Out-File -FilePath $env:GITHUB_PATH -Append
161+ shell : pwsh
119162
120163 - name : Verify FFmpeg installation
121164 run : |
122165 ffmpeg -version
123166 shell : bash
167+ continue-on-error : true
124168
125- - name : Run basic tests
169+ - name : Create directories
126170 run : |
127- python test_run.py
128- continue-on-error : true
171+ mkdir -p test_output tests
172+ if [ ! -f tests/__init__.py ]; then touch tests/__init__.py; fi
173+ shell : bash
129174
130- - name : Test with pytest if available
175+ # Create basic test file if none exists
176+ - name : Create basic test file if needed
131177 run : |
132- if [ -d "tests" ]; then
133- pytest --cov=. --cov-report=xml
134- else
135- echo "No tests directory found. Skipping pytest."
136- echo "Consider adding proper tests for better code quality."
178+ if [ ! -f tests/test_basic.py ]; then
179+ echo '
180+ import sys
181+ import os
182+ import pytest
183+
184+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
185+
186+ def test_import():
187+ """Test that the main module can be imported."""
188+ try:
189+ import Snatch
190+ assert Snatch.__name__ == "Snatch"
191+ except ImportError:
192+ pytest.skip("Snatch module not found")
193+ ' > tests/test_basic.py
137194 fi
138195 shell : bash
196+
197+ - name : Run basic tests
198+ run : |
199+ python test_run.py
139200 continue-on-error : true
140201
141- - name : Upload coverage to Codecov
142- uses : codecov/codecov-action@v3
143- with :
144- file : ./coverage.xml
145- flags : ${{ matrix.os }},python${{ matrix.python-version }}
146- name : ${{ matrix.os }}-python${{ matrix.python-version }}
147- fail_ci_if_error : false
202+ - name : Test with pytest
203+ run : |
204+ pytest --cov=. --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml --html=pytest_report.html
205+ shell : bash
148206 continue-on-error : true
149207
150208 - name : Upload test results
@@ -154,13 +212,14 @@ jobs:
154212 name : test-results-${{ matrix.os }}-py${{ matrix.python-version }}
155213 path : |
156214 coverage.xml
157- pytest-report.html
158- test_output.log
159- retention-days : 7
160- continue-on-error : true
215+ htmlcov/
216+ pytest_report.html
217+ junit/
218+ test_output/
219+ retention-days : 14
161220
162221 security-scan :
163- name : Security Scanning
222+ name : Security Scan
164223 runs-on : ubuntu-latest
165224 needs : lint
166225 steps :
@@ -176,24 +235,25 @@ jobs:
176235 run : |
177236 python -m pip install --upgrade pip
178237 pip install bandit safety
238+ pip install -r requirements.txt
179239
180240 - name : Run Bandit security scanner
181241 run : |
182- bandit -r Snatch.py setup.py setup_ffmpeg.py interactive_mode.py -f json -o bandit-results.json
242+ mkdir -p security_reports
243+ bandit -r . -f json -o security_reports/bandit-results.json -x tests,venv,.venv
183244 continue-on-error : true
184245
185246 - name : Check dependencies for vulnerabilities
186247 run : |
187- safety check -r requirements.txt --output json --save safety-results.json
248+ safety check -r requirements.txt --output json --save security_reports/ safety-results.json || true
188249 continue-on-error : true
189250
190251 - name : Upload security scan results
191252 uses : actions/upload-artifact@v4
192253 with :
193254 name : security-scan-results
194- path : |
195- bandit-results.json
196- safety-results.json
255+ path : security_reports/
256+ retention-days : 14
197257
198258 build :
199259 name : Build Package
@@ -203,7 +263,7 @@ jobs:
203263 - name : Checkout repository
204264 uses : actions/checkout@v4
205265 with :
206- fetch-depth : 0 # Fetch all history for proper versioning
266+ fetch-depth : 0
207267
208268 - name : Set up Python
209269 uses : actions/setup-python@v5
@@ -218,22 +278,22 @@ jobs:
218278
219279 - name : Build package
220280 run : |
221- python setup.py sdist bdist_wheel
281+ python -m build -- sdist --wheel .
222282
223283 - name : Check package with twine
224284 run : |
225285 twine check dist/*
226- continue-on-error : true
227286
228287 - name : Store built package
229288 uses : actions/upload-artifact@v4
230289 with :
231290 name : dist
232291 path : dist/
292+ retention-days : 30
233293
234294 - name : Test installation from wheel
235295 run : |
236- pip install dist/*.whl
296+ pip install --force-reinstall dist/*.whl
237297
238298 readme-badge :
239299 name : Update README Badge
@@ -257,3 +317,23 @@ jobs:
257317 label : CI
258318 message : passing
259319 color : green
320+
321+ notify :
322+ name : Notify on completion
323+ needs : [build, readme-badge]
324+ if : always()
325+ runs-on : ubuntu-latest
326+ steps :
327+ - name : Set job status
328+ id : status
329+ run : |
330+ if [[ "${{ needs.build.result }}" == "success" ]]; then
331+ echo "STATUS=✅ CI Pipeline completed successfully" >> $GITHUB_OUTPUT
332+ else
333+ echo "STATUS=⚠️ CI Pipeline completed with issues" >> $GITHUB_OUTPUT
334+ fi
335+
336+ - name : Print completion message
337+ run : |
338+ echo "${{ steps.status.outputs.STATUS }}"
339+ echo "All artifacts have been uploaded and are available in the Actions tab"
0 commit comments