Les quatre jobs existaient ; aucun ne verifiait ce qu'il annoncait.
security-audit
`pip-audit --require-hashes --no-deps || pip-audit`. L'etape
d'installation ne posait que pip-audit, et aucune des deux formes ne
nommait le fichier d'exigences : le repli auditait l'environnement du
runner, qui ne contenait que pip-audit lui-meme. Le job passait au vert
sans avoir examine une seule dependance de l'application. Remplace par
`pip-audit -r requirements.txt`.
security-scan
Appelait `python security_scan.py`, alors que le fichier se trouve dans
app/supporting_scripts/. En echec a chaque execution depuis le
deplacement du fichier. Trois autres defauts sont apparus en le faisant
tourner :
- la CI passe --skip-http, un argument que l'argparse du script
n'acceptait pas : sortie en erreur 2 meme avec le bon chemin.
- check_dependencies lisait data['dependencies'] comme la liste des
vulnerabilites. Ce tableau liste en realite TOUTES les dependances,
chacune portant un champ vulns vide si le paquet est sain. Les ~45
paquets installes etaient donc signales vulnerables a chaque
execution. Le filtrage se fait desormais sur vulns non vide.
- check_flask_config interceptait son exception et renvoyait quand
meme all_ok : ne pas reussir a charger l'application comptait comme
un controle reussi. La section la plus importante du rapport n'avait
jamais tourne. Elle renvoie desormais False, et l'import fonctionne
grace a l'ajout de la racine du projet dans sys.path.
- la banniere en caracteres semi-graphiques faisait planter le script
sur une console Windows en cp1252, la plateforme meme du projet.
Passee en ASCII.
lint
Ruff n'avait aucun fichier de configuration : le job tournait sur le jeu
de regles par defaut. La configuration vit maintenant dans pyproject.toml.
`ruff format --check` est retire pour l'instant : la base n'ayant jamais
ete formatee, il echouerait sur 62 fichiers sur 64 pour des raisons
etrangeres a la correction. Reformatage puis application : QUA-002.
test
Un `echo` protege par continue-on-error : le job annoncait un succes
sans rien executer. Il lance desormais pytest avec couverture, et bloque.
permissions: contents: read au niveau du workflow, aucune etape n'ecrivant
dans le depot.
Deploiement Gitea
actions/checkout@v7 n'existe pas (derniere majeure : v5) : le workflow
echouait des sa premiere etape. Ramene a v4.
Le miroir lftp poussait l'integralite de l'arbre de travail, dont
clear_db.py -- un script qui vide toutes les tables et recree
admin/password -- vers le noeud de production. Liste d'exclusions ajoutee.
--delete reste volontairement absent : les contrats televerses, les
journaux et le .env du serveur vivent sous la racine de deploiement et
sont absents du depot ; les supprimer detruirait des donnees.
Le workflow de deploiement n'a pas pu etre execute depuis ici : la
syntaxe lftp reste a valider lors du prochain deploiement manuel.
Co-Authored-By: Claude Opus 5 <[email protected]>
115 lines
3.5 KiB
YAML
115 lines
3.5 KiB
YAML
name: CI - Security & Lint
|
|
|
|
on:
|
|
push:
|
|
branches: [main, master]
|
|
pull_request:
|
|
branches: [main, master]
|
|
workflow_dispatch: # Allow manual triggers
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
# Least privilege: nothing here writes back to the repository.
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
PYTHON_VERSION: '3.12'
|
|
|
|
jobs:
|
|
security-audit:
|
|
name: Security Audit
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
cache: 'pip'
|
|
|
|
- name: Install pip-audit
|
|
run: pip install pip-audit==2.9.0
|
|
|
|
# Previously: `pip-audit --require-hashes --no-deps || pip-audit`.
|
|
# Neither form named the requirements file, so the fallback audited the
|
|
# runner's environment — which contained pip-audit and nothing else.
|
|
# The job passed green while checking none of the application's
|
|
# dependencies. -r makes it audit what the application actually pins.
|
|
- name: Scan declared dependencies for known vulnerabilities
|
|
run: pip-audit -r requirements.txt
|
|
|
|
lint:
|
|
name: Lint with Ruff
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
|
|
- name: Install ruff
|
|
run: pip install ruff==0.14.4
|
|
|
|
# Rule selection and per-file ignores live in pyproject.toml. Before it
|
|
# existed, this step ran ruff's bare defaults with no configuration.
|
|
- name: Run ruff linter
|
|
run: ruff check . --output-format=github
|
|
|
|
# `ruff format --check` is deliberately absent for now: the codebase has
|
|
# never been formatted, so it would fail on 62 of 64 files for reasons
|
|
# unrelated to correctness. Reformatting in one isolated commit and then
|
|
# enforcing it here is tracked as QUA-002.
|
|
|
|
security-scan:
|
|
name: Security Scan
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
cache: 'pip'
|
|
|
|
- name: Install app dependencies
|
|
run: pip install -r requirements.txt -r requirements-dev.txt
|
|
|
|
# The path was `security_scan.py`, but the script lives under
|
|
# app/supporting_scripts/. The step had therefore failed on every run
|
|
# since the file was moved.
|
|
- name: Run security scan
|
|
env:
|
|
SECRET_KEY: ${{ secrets.CI_SECRET_KEY || 'test-key-not-for-production-1234567890' }}
|
|
FLASK_DEBUG: 'false'
|
|
run: python app/supporting_scripts/security_scan.py --skip-http
|
|
|
|
test:
|
|
name: Tests
|
|
runs-on: ubuntu-latest
|
|
needs: [security-audit, lint]
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
cache: 'pip'
|
|
|
|
- name: Install dependencies
|
|
run: pip install -r requirements.txt -r requirements-dev.txt
|
|
|
|
# Previously an `echo` guarded by continue-on-error: the job reported
|
|
# success without executing anything. The suite needs no environment
|
|
# variables and no database server: create_app() takes its configuration
|
|
# as an argument and the fixtures use a temporary SQLite file.
|
|
- name: Run tests
|
|
run: pytest --cov=app --cov-report=term-missing --cov-report=xml
|