Aug 26 - Enhance security 2
CI / Python lint (flake8) (push) Has been cancelled
CI / Python syntax check (push) Has been cancelled
CI / Alembic migration chain (push) Has been cancelled
CI / JavaScript syntax check (push) Has been cancelled
CI / Pytest (push) Has been cancelled
CI / Build extension zip (push) Has been cancelled
CI / Python lint (flake8) (push) Has been cancelled
CI / Python syntax check (push) Has been cancelled
CI / Alembic migration chain (push) Has been cancelled
CI / JavaScript syntax check (push) Has been cancelled
CI / Pytest (push) Has been cancelled
CI / Build extension zip (push) Has been cancelled
This commit is contained in:
+34
-6
@@ -9,6 +9,7 @@
|
||||
# syntax-check — ast.parse all Python files
|
||||
# migration-check — verify Alembic chain has single head
|
||||
# js-syntax — node syntax check on all JS files
|
||||
# tests — pytest suite (in-memory SQLite, no MySQL needed)
|
||||
# build-extension — zip Chrome and Firefox extensions
|
||||
|
||||
name: CI
|
||||
@@ -48,12 +49,23 @@ jobs:
|
||||
- name: Check all Python files parse cleanly
|
||||
run: |
|
||||
python3 - << 'EOF'
|
||||
import ast, sys, pathlib
|
||||
import ast, sys, pathlib, itertools
|
||||
|
||||
# Root-level modules (wsgi, run, reset_db, gunicorn.conf) were not
|
||||
# covered before, so a syntax error in the Gunicorn config or the WSGI
|
||||
# entrypoint reached production without CI noticing.
|
||||
paths = list(itertools.chain(
|
||||
pathlib.Path('app').rglob('*.py'),
|
||||
pathlib.Path('tests').rglob('*.py'),
|
||||
pathlib.Path('scripts').rglob('*.py'),
|
||||
pathlib.Path('migrations/versions').rglob('*.py'),
|
||||
pathlib.Path('.').glob('*.py'),
|
||||
))
|
||||
|
||||
failures = []
|
||||
for path in pathlib.Path('app').rglob('*.py'):
|
||||
for path in paths:
|
||||
try:
|
||||
ast.parse(path.read_text())
|
||||
ast.parse(path.read_text(encoding='utf-8'))
|
||||
except SyntaxError as e:
|
||||
failures.append(f"{path}: {e}")
|
||||
|
||||
@@ -61,8 +73,7 @@ jobs:
|
||||
print(f"FAIL: {f}")
|
||||
if failures:
|
||||
sys.exit(1)
|
||||
count = len(list(pathlib.Path('app').rglob('*.py')))
|
||||
print(f"OK: {count} Python files parsed cleanly")
|
||||
print(f"OK: {len(paths)} Python files parsed cleanly")
|
||||
EOF
|
||||
|
||||
# ── Alembic migration chain ──────────────────────────────────────────────────
|
||||
@@ -130,11 +141,28 @@ jobs:
|
||||
[ $FAILED -eq 0 ] && echo "OK: all JS files parsed cleanly"
|
||||
exit $FAILED
|
||||
|
||||
# ── Test suite ───────────────────────────────────────────────────────────────
|
||||
# Runs against in-memory SQLite (see app/config.py TestingConfig) so no MySQL
|
||||
# service is needed on the host-mode runner. That means these tests cover
|
||||
# application logic and flow, not MySQL-specific behaviour — schema changes
|
||||
# still need a real `flask db upgrade` against MySQL before deploying.
|
||||
tests:
|
||||
name: Pytest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements.txt -r requirements-dev.txt --quiet --break-system-packages
|
||||
|
||||
- name: Run test suite
|
||||
run: python3 -m pytest tests/ -q
|
||||
|
||||
# ── Extension build ──────────────────────────────────────────────────────────
|
||||
build-extension:
|
||||
name: Build extension zip
|
||||
runs-on: ubuntu-latest
|
||||
needs: [syntax-check, js-syntax]
|
||||
needs: [syntax-check, js-syntax, tests]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user