Skip to content

Commit 5e22cd0

Browse files
Create ci.yml
1 parent 4529a4a commit 5e22cd0

File tree

1 file changed

+257
-0
lines changed

1 file changed

+257
-0
lines changed

.github/workflows/ci.yml

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
name: CI Pipeline
2+
3+
on:
4+
push:
5+
branches: [ "main", "develop" ]
6+
paths:
7+
- 'Snatch.py'
8+
- 'setup.py'
9+
- 'setup_ffmpeg.py'
10+
- 'tests/**'
11+
- 'requirements.txt'
12+
- '.github/workflows/**'
13+
pull_request:
14+
branches: [ "main", "develop" ]
15+
paths:
16+
- 'Snatch.py'
17+
- 'setup.py'
18+
- 'setup_ffmpeg.py'
19+
- 'tests/**'
20+
- 'requirements.txt'
21+
- '.github/workflows/**'
22+
schedule:
23+
- cron: '0 0 * * 0' # Run weekly on Sundays
24+
workflow_dispatch: # Allow manual triggering
25+
26+
jobs:
27+
lint:
28+
name: Code Quality
29+
runs-on: ubuntu-latest
30+
steps:
31+
- name: Checkout repository
32+
uses: actions/checkout@v4
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: '3.10'
38+
cache: 'pip' # Enable pip caching
39+
40+
- name: Install dependencies
41+
run: |
42+
python -m pip install --upgrade pip
43+
pip install flake8 black isort mypy pylint pydocstyle pycodestyle
44+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
45+
pip install -e .
46+
47+
- name: Check formatting with Black
48+
run: black --check Snatch.py setup.py setup_ffmpeg.py tests/
49+
50+
- name: Check imports with isort
51+
run: isort --check-only --profile black Snatch.py setup.py setup_ffmpeg.py tests/
52+
53+
- name: Lint with flake8
54+
run: |
55+
# Stop the build if there are Python syntax errors or undefined names
56+
flake8 Snatch.py setup.py setup_ffmpeg.py tests/ --count --select=E9,F63,F7,F82 --show-source --statistics
57+
# Exit-zero treats all errors as warnings
58+
flake8 Snatch.py setup.py setup_ffmpeg.py tests/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
59+
60+
- name: Type checking with mypy
61+
run: |
62+
mypy --ignore-missing-imports Snatch.py setup.py setup_ffmpeg.py
63+
continue-on-error: true
64+
65+
- name: Check with pylint
66+
run: |
67+
pylint --disable=all --enable=unused-import,unused-variable,unused-argument,undefined-variable Snatch.py setup.py setup_ffmpeg.py
68+
continue-on-error: true
69+
70+
- name: Check docstrings with pydocstyle
71+
run: |
72+
pydocstyle Snatch.py
73+
continue-on-error: true
74+
75+
- name: Generate linting reports
76+
run: |
77+
mkdir -p reports
78+
flake8 Snatch.py setup.py setup_ffmpeg.py tests/ --output-file=reports/flake8.txt
79+
pylint Snatch.py setup.py setup_ffmpeg.py -f json > reports/pylint.json || true
80+
81+
- name: Upload linting reports
82+
uses: actions/upload-artifact@v3
83+
with:
84+
name: linting-reports
85+
path: reports/
86+
87+
test:
88+
name: Test
89+
runs-on: ${{ matrix.os }}
90+
needs: lint
91+
strategy:
92+
matrix:
93+
os: [ubuntu-latest, windows-latest, macos-latest]
94+
python-version: ['3.8', '3.9', '3.10', '3.11']
95+
exclude:
96+
# Optionally exclude some combinations to save CI minutes
97+
- os: macos-latest
98+
python-version: '3.8'
99+
fail-fast: false
100+
101+
steps:
102+
- name: Checkout repository
103+
uses: actions/checkout@v4
104+
105+
- name: Set up Python ${{ matrix.python-version }}
106+
uses: actions/setup-python@v5
107+
with:
108+
python-version: ${{ matrix.python-version }}
109+
cache: 'pip'
110+
111+
- name: Install dependencies
112+
run: |
113+
python -m pip install --upgrade pip
114+
pip install pytest pytest-cov pytest-xdist pytest-timeout pytest-mock
115+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
116+
pip install -e .
117+
shell: bash
118+
119+
- name: Install FFmpeg (Ubuntu)
120+
if: matrix.os == 'ubuntu-latest'
121+
run: |
122+
sudo apt-get update
123+
sudo apt-get install -y ffmpeg
124+
125+
- name: Install FFmpeg (macOS)
126+
if: matrix.os == 'macos-latest'
127+
run: |
128+
brew install ffmpeg
129+
130+
- name: Install FFmpeg (Windows)
131+
if: matrix.os == 'windows-latest'
132+
run: |
133+
choco install ffmpeg -y
134+
135+
- name: Verify FFmpeg installation
136+
run: |
137+
ffmpeg -version
138+
shell: bash
139+
140+
- name: Run unit tests
141+
run: |
142+
pytest tests/unit --cov=. --cov-report=xml --junitxml=test-results.xml -v
143+
144+
- name: Run integration tests
145+
run: |
146+
pytest tests/integration --cov=. --cov-append --cov-report=xml -v --timeout=300
147+
148+
- name: Test edge cases and performance
149+
run: |
150+
pytest tests/performance --cov=. --cov-append --cov-report=xml -v -xvs
151+
continue-on-error: true # Performance tests may be flaky
152+
153+
- name: Upload test results
154+
uses: actions/upload-artifact@v3
155+
if: always()
156+
with:
157+
name: test-results-${{ matrix.os }}-${{ matrix.python-version }}
158+
path: test-results.xml
159+
160+
- name: Upload coverage to Codecov
161+
uses: codecov/codecov-action@v3
162+
with:
163+
file: ./coverage.xml
164+
flags: ${{ matrix.os }},python${{ matrix.python-version }}
165+
name: ${{ matrix.os }}-python${{ matrix.python-version }}
166+
fail_ci_if_error: false
167+
168+
- name: Generate HTML coverage report
169+
run: |
170+
pip install coverage
171+
coverage html
172+
173+
- name: Upload coverage report
174+
uses: actions/upload-artifact@v3
175+
with:
176+
name: coverage-report-${{ matrix.os }}-${{ matrix.python-version }}
177+
path: htmlcov/
178+
179+
security-scan:
180+
name: Security Scanning
181+
runs-on: ubuntu-latest
182+
needs: lint
183+
steps:
184+
- name: Checkout repository
185+
uses: actions/checkout@v4
186+
187+
- name: Set up Python
188+
uses: actions/setup-python@v5
189+
with:
190+
python-version: '3.10'
191+
192+
- name: Install dependencies
193+
run: |
194+
python -m pip install --upgrade pip
195+
pip install bandit safety
196+
197+
- name: Run Bandit security scanner
198+
run: |
199+
bandit -r Snatch.py setup.py setup_ffmpeg.py -f json -o bandit-results.json
200+
continue-on-error: true
201+
202+
- name: Check dependencies for vulnerabilities
203+
run: |
204+
safety check -r requirements.txt --output json --save safety-results.json
205+
continue-on-error: true
206+
207+
- name: Upload security scan results
208+
uses: actions/upload-artifact@v3
209+
with:
210+
name: security-scan-results
211+
path: |
212+
bandit-results.json
213+
safety-results.json
214+
215+
build:
216+
name: Build Package
217+
needs: [test, security-scan]
218+
runs-on: ubuntu-latest
219+
steps:
220+
- name: Checkout repository
221+
uses: actions/checkout@v4
222+
with:
223+
fetch-depth: 0 # Fetch all history for proper versioning
224+
225+
- name: Set up Python
226+
uses: actions/setup-python@v5
227+
with:
228+
python-version: '3.10'
229+
cache: 'pip'
230+
231+
- name: Install dependencies
232+
run: |
233+
python -m pip install --upgrade pip
234+
pip install build wheel setuptools twine check-manifest
235+
236+
- name: Verify MANIFEST.in
237+
run: check-manifest
238+
continue-on-error: true
239+
240+
- name: Build package
241+
run: |
242+
python -m build
243+
244+
- name: Check package with twine
245+
run: |
246+
twine check dist/*
247+
248+
- name: Store built package
249+
uses: actions/upload-artifact@v3
250+
with:
251+
name: dist
252+
path: dist/
253+
254+
- name: Verify install from wheel
255+
run: |
256+
pip install dist/*.whl
257+
python -c "import Snatch; print(f'Successfully imported version {Snatch.__version__}')"

0 commit comments

Comments
 (0)