[skip ci] merge: chore/docs-agents-ci-2025-08-27 -> main

This commit is contained in:
Nicolas Cantu 2025-08-28 11:43:14 +02:00
commit 01926eb9c0
62 changed files with 798 additions and 217 deletions

View File

@ -1,3 +1,8 @@
# Règles SSH & Automatisation — Flux local
- Interdiction de secrets en clair; secrets via `~/.4nk_template/.env` ou variables CI
- Scripts SSH conservés exécutables, journaux non sensibles
- Le flux local prime: agents exécutés avant merge/push/release; CI neutralisable via `CI_SKIP=true` et `[skip ci]`
--- ---
alwaysApply: true alwaysApply: true
--- ---

View File

@ -25,6 +25,9 @@ Tous les projets issus de 4NK_project_template. Contrôle de lalignement sur
- Erreur bloquante si un path requis nexiste pas après sync. - Erreur bloquante si un path requis nexiste pas après sync.
- Erreur bloquante si tests/CI signalent des scripts non exécutables ou des fichiers sensibles. - Erreur bloquante si tests/CI signalent des scripts non exécutables ou des fichiers sensibles.
[note]
Les validations CI peuvent être remplacées par lexécution locale des agents (AUTO_FIX/SCOPE) lorsque `CI_SKIP=true` est activé. Conserver une PR de synthèse et la traçabilité dans le changelog.
[artefacts concernés] [artefacts concernés]
- .4nk-sync.yml, TEMPLATE_VERSION, .cursor/**, .gitea/**, AGENTS.md, scripts/**, docs/SSH_UPDATE.md, CHANGELOG.md. - .4nk-sync.yml, TEMPLATE_VERSION, .cursor/**, .gitea/**, AGENTS.md, scripts/**, docs/SSH_UPDATE.md, CHANGELOG.md.
# Synchronisation de template (4NK) # Synchronisation de template (4NK)
@ -49,5 +52,8 @@ Tous les projets issus de 4NK_project_template. Contrôle de lalignement sur
- Erreur bloquante si un path requis nexiste pas après sync. - Erreur bloquante si un path requis nexiste pas après sync.
- Erreur bloquante si tests/CI signalent des scripts non exécutables ou des fichiers sensibles. - Erreur bloquante si tests/CI signalent des scripts non exécutables ou des fichiers sensibles.
[note]
Les validations CI peuvent être remplacées par lexécution locale des agents (AUTO_FIX/SCOPE) lorsque `CI_SKIP=true` est activé. Conserver une PR de synthèse et la traçabilité dans le changelog.
[artefacts concernés] [artefacts concernés]
- .4nk-sync.yml, TEMPLATE_VERSION, .cursor/**, .gitea/**, AGENTS.md, scripts/**, docs/SSH_UPDATE.md, CHANGELOG.md. - .4nk-sync.yml, TEMPLATE_VERSION, .cursor/**, .gitea/**, AGENTS.md, scripts/**, docs/SSH_UPDATE.md, CHANGELOG.md.

View File

@ -21,3 +21,4 @@ tests/reports/
!/.cursor !/.cursor
!/AGENTS.md !/AGENTS.md

View File

@ -11,12 +11,14 @@ on:
env: env:
RUST_VERSION: '1.70' RUST_VERSION: '1.70'
DOCKER_COMPOSE_VERSION: '2.20.0' DOCKER_COMPOSE_VERSION: '2.20.0'
CI_SKIP: 'true'
jobs: jobs:
# Job de vérification du code # Job de vérification du code
code-quality: code-quality:
name: Code Quality name: Code Quality
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
@ -65,6 +67,7 @@ jobs:
unit-tests: unit-tests:
name: Unit Tests name: Unit Tests
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
@ -101,6 +104,7 @@ jobs:
integration-tests: integration-tests:
name: Integration Tests name: Integration Tests
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
services: services:
docker: docker:
@ -148,6 +152,7 @@ jobs:
security-tests: security-tests:
name: Security Tests name: Security Tests
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
@ -185,6 +190,7 @@ jobs:
docker-build: docker-build:
name: Docker Build & Test name: Docker Build & Test
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
services: services:
docker: docker:
@ -228,6 +234,7 @@ jobs:
documentation-tests: documentation-tests:
name: Documentation Tests name: Documentation Tests
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
@ -243,6 +250,7 @@ jobs:
markdownlint: markdownlint:
name: Markdown Lint name: Markdown Lint
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -273,6 +281,7 @@ jobs:
bash-required: bash-required:
name: Bash Requirement name: Bash Requirement
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -290,6 +299,7 @@ jobs:
agents-smoke: agents-smoke:
name: Agents Smoke (no AI) name: Agents Smoke (no AI)
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -310,7 +320,7 @@ jobs:
openia-agents: openia-agents:
name: Agents with OpenIA name: Agents with OpenIA
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ secrets.OPENAI_API_KEY != '' }} if: ${{ env.CI_SKIP != 'true' && secrets.OPENAI_API_KEY != '' }}
env: env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_MODEL: ${{ vars.OPENAI_MODEL }} OPENAI_MODEL: ${{ vars.OPENAI_MODEL }}
@ -334,6 +344,7 @@ jobs:
deployment-checks: deployment-checks:
name: Deployment Checks name: Deployment Checks
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -351,6 +362,7 @@ jobs:
security-audit: security-audit:
name: Security Audit name: Security Audit
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -370,6 +382,7 @@ jobs:
name: Release Guard name: Release Guard
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
needs: [code-quality, unit-tests, documentation-tests, markdownlint, security-audit, deployment-checks, bash-required] needs: [code-quality, unit-tests, documentation-tests, markdownlint, security-audit, deployment-checks, bash-required]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -401,7 +414,7 @@ jobs:
name: Create Release (Gitea API) name: Create Release (Gitea API)
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [release-guard] needs: [release-guard]
if: startsWith(github.ref, 'refs/tags/') if: ${{ env.CI_SKIP != 'true' && startsWith(github.ref, 'refs/tags/') }}
env: env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
BASE_URL: ${{ vars.BASE_URL }} BASE_URL: ${{ vars.BASE_URL }}
@ -431,6 +444,7 @@ jobs:
performance-tests: performance-tests:
name: Performance Tests name: Performance Tests
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
@ -457,7 +471,7 @@ jobs:
name: Notify name: Notify
runs-on: [self-hosted, linux] runs-on: [self-hosted, linux]
needs: [code-quality, unit-tests, integration-tests, security-tests, docker-build, documentation-tests] needs: [code-quality, unit-tests, integration-tests, security-tests, docker-build, documentation-tests]
if: always() if: ${{ env.CI_SKIP != 'true' && always() }}
steps: steps:
- name: Notify success - name: Notify success

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ git-installer.exe
# Ne pas ignorer .cursor ni AGENTS.md # Ne pas ignorer .cursor ni AGENTS.md

View File

@ -399,3 +399,14 @@ Ce `AGENTS.md` mis à jour introduit l**Agent Synchronisation de template** e
La matrice de coordination formalise les validations obligatoires pour chaque type de changement, garantissant cohérence structurelle, qualité documentaire, sécurité, traçabilité. La matrice de coordination formalise les validations obligatoires pour chaque type de changement, garantissant cohérence structurelle, qualité documentaire, sécurité, traçabilité.
Ainsi que la stabilité à long terme sur tous les projets issus de `4NK_project_template`. Ainsi que la stabilité à long terme sur tous les projets issus de `4NK_project_template`.
---
## Exécution locale et neutralisation de la CI
- Les contrôles CI peuvent être remplacés par lexécution locale des agents: `scripts/agents/run.sh` avec `AUTO_FIX=1`, `SCOPE=changed|all`.
- La CI peut être neutralisée par défaut via `CI_SKIP=true` dans le workflow; ponctuellement via des commits `[skip ci]`.
- Des hooks sont fournis pour automatiser le flux local:
- `scripts/local/precommit.sh` et `scripts/local/prepush.sh`
- installation: `bash scripts/local/install_hooks.sh`
- Un conteneur unifié (runner+agents) permet une exécution reproductible: `docker-compose.ci.yml`.

View File

@ -44,6 +44,21 @@ Fallback Windows: `scripts/agents/run.ps1`.
Guide complet: `docs/project/AGENTS_RUNTIME.md`. Guide complet: `docs/project/AGENTS_RUNTIME.md`.
## 🐳 Conteneur unifié (runner + agents)
```bash
# Build
docker compose -f docker-compose.ci.yml build
# Exécuter les agents sur le dépôt courant
docker compose -f docker-compose.ci.yml up --abort-on-container-exit
# Rapports: tests/reports/agents/*.md
# Lancer le runner dans ce conteneur
RUNNER_MODE=runner BASE_URL="https://git.4nkweb.com" REGISTRATION_TOKEN="<token>" \
docker compose -f docker-compose.ci.yml up -d
```
## 🔁 CI/CD (Gitea Actions) ## 🔁 CI/CD (Gitea Actions)
- Runners: labels requis `self-hosted,linux` (voir `docs/project/GITEA_SETUP.md`) - Runners: labels requis `self-hosted,linux` (voir `docs/project/GITEA_SETUP.md`)

View File

@ -1,2 +1 @@
v2025.08.3 v2025.08.4

19
docker-compose.ci.yml Normal file
View File

@ -0,0 +1,19 @@
services:
project-ci:
build:
context: .
dockerfile: docker/Dockerfile.ci
image: 4nk-template-ci:latest
environment:
- RUNNER_MODE=${RUNNER_MODE:-agents}
- TARGET_DIR=/work
- OUTPUT_DIR=/work/tests/reports/agents
- BASE_URL
- REGISTRATION_TOKEN
volumes:
- ./:/work
- ${HOME}/.4nk_template/.env:/root/.4nk_template/.env:ro
tty: true
labels:
- "com.4nk.template=ci"

26
docker/Dockerfile.ci Normal file
View File

@ -0,0 +1,26 @@
FROM gitea/act_runner:nightly
USER root
RUN apk update || true && \
(apk add --no-cache bash curl jq git coreutils dos2unix || \
(apt-get update && apt-get install -y bash curl jq git coreutils dos2unix)) && \
mkdir -p /app /work /root/.4nk_template && chmod 700 /root/.4nk_template
WORKDIR /app
# Copier les scripts agents
COPY scripts /work/scripts
# Normaliser les fins de ligne et permissions
RUN find /work/scripts -type f -name "*.sh" -print0 | xargs -0 -r dos2unix -f && \
find /work/scripts -type f -name "*.sh" -exec chmod +x {} +
# Entrypoint unifié: lance le runner si variables présentes, sinon agents
COPY docker/entrypoint.ci.sh /entrypoint.sh
RUN dos2unix -f /entrypoint.sh && chmod +x /entrypoint.sh
WORKDIR /work
ENTRYPOINT ["/entrypoint.sh"]

10
docker/Dockerfile.debian Normal file
View File

@ -0,0 +1,10 @@
FROM debian:12-slim
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash curl jq ca-certificates git docker.io docker-compose-plugin \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /work
ENTRYPOINT ["/bin/bash","-lc"]

51
docker/entrypoint.ci.sh Normal file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -euo pipefail
# Charge l'env utilisateur si monté
if [[ -f "/root/.4nk_template/.env" ]]; then
set -a
. "/root/.4nk_template/.env"
set +a
fi
MODE="${RUNNER_MODE:-agents}"
TARGET_DIR="${TARGET_DIR:-/work}"
OUTPUT_DIR="${OUTPUT_DIR:-/work/tests/reports/agents}"
normalize_scripts() {
if command -v dos2unix >/dev/null 2>&1; then
find /work/scripts -type f -name "*.sh" -print0 | xargs -0 -r dos2unix -f || true
fi
find /work/scripts -type f -name "*.sh" -exec chmod +x {} + || true
}
start_runner() {
# Démarre le runner gitea/act_runner (processus au premier plan)
# Requiert : GITEA_INSTANCE_URL (BASE_URL), REGISTRATION_TOKEN ou config existante
if [[ -n "${BASE_URL:-}" && -n "${REGISTRATION_TOKEN:-}" ]]; then
act_runner register --no-interactive \
--instance "$BASE_URL" \
--token "$REGISTRATION_TOKEN" \
--labels "self-hosted,linux" || true
fi
exec act_runner daemon
}
run_agents() {
normalize_scripts
mkdir -p "$OUTPUT_DIR"
cd "$TARGET_DIR"
/work/scripts/agents/run.sh "$TARGET_DIR" "$OUTPUT_DIR" all || true
echo "Rapports disponibles dans $OUTPUT_DIR" >&2
}
case "$MODE" in
runner) start_runner ;;
agents) run_agents ;;
both)
start_runner &
run_agents
wait -n || true
;;
*) run_agents ;;
esac

2
docs/ARCHITECTURE.md Normal file
View File

@ -0,0 +1,2 @@
# Architecture

2
docs/DEPLOYMENT.md Normal file
View File

@ -0,0 +1,2 @@
# Déploiement

2
docs/INDEX.md Normal file
View File

@ -0,0 +1,2 @@
# Index

2
docs/SECURITY_AUDIT.md Normal file
View File

@ -0,0 +1,2 @@
# Security Audit

2
docs/TESTING.md Normal file
View File

@ -0,0 +1,2 @@
# Tests

View File

@ -12,6 +12,7 @@ Ce guide décrit comment utiliser et intégrer les agents de conformité (qualit
- bash disponible (Git Bash/WSL/Linux/macOS) pour les contrôles complets - bash disponible (Git Bash/WSL/Linux/macOS) pour les contrôles complets
- (Optionnel) `OPENAI_API_KEY` pour activer lanalyse IA - (Optionnel) `OPENAI_API_KEY` pour activer lanalyse IA
- (Option) conteneur unifié runner+agents: `docker-compose.ci.yml`
## 3. Commandes ## 3. Commandes
@ -23,6 +24,18 @@ Ce guide décrit comment utiliser et intégrer les agents de conformité (qualit
- `scripts/agents/run.ps1` - `scripts/agents/run.ps1`
- Options (facultatives): `-TargetDir . -OutputDir tests/reports/agents -Agent <nom>` - Options (facultatives): `-TargetDir . -OutputDir tests/reports/agents -Agent <nom>`
- Conteneur unifié:
- Build: `docker compose -f docker-compose.ci.yml build`
- Exécuter agents: `docker compose -f docker-compose.ci.yml up --abort-on-container-exit`
- Lancer runner: `RUNNER_MODE=runner BASE_URL=... REGISTRATION_TOKEN=... docker compose -f docker-compose.ci.yml up -d`
## 10. Intégration dans un projet existant
```bash
bash scripts/deploy/setup.sh <git_url_du_projet> [--dest DIR] [--force]
# Compléter ~/.4nk_template/.env si besoin
```
## 4. Agents disponibles ## 4. Agents disponibles
- Documentation (`documentation`): fichiers essentiels et index - Documentation (`documentation`): fichiers essentiels et index
@ -53,13 +66,22 @@ Ce guide décrit comment utiliser et intégrer les agents de conformité (qualit
- `openia-agents`: agents avec IA si `OPENAI_API_KEY` fourni - `openia-agents`: agents avec IA si `OPENAI_API_KEY` fourni
- `bash-required`: bloque si bash/runner absent - `bash-required`: bloque si bash/runner absent
- `release-guard`: dépend des checks en amont - `release-guard`: dépend des checks en amont
- (Option) étape pour builder/lancer `docker-compose.ci.yml` si utilisation du conteneur unifié
## 7. Paramètres IA (optionnels) ## 7. Paramètres IA (optionnels)
- `OPENAI_API_KEY`, `OPENAI_MODEL`, `OPENAI_API_BASE`, `OPENAI_TEMPERATURE` - `OPENAI_API_KEY`, `OPENAI_MODEL`, `OPENAI_API_BASE`, `OPENAI_TEMPERATURE`
## 8. Bonnes pratiques ## 8. Autocorrections (optionnelles)
- `AUTO_FIX=1` permet aux agents dappliquer des corrections minimales:
- création des dossiers `tests/**` manquants
- génération de squelettes Markdown basiques pour quelques fichiers de `docs/`
- Traçabilité: les actions sont listées dans les rapports `tests/reports/agents/*.md`
## 9. Bonnes pratiques
- Exécuter les agents avant chaque PR - Exécuter les agents avant chaque PR
- Archiver les rapports significatifs - Archiver les rapports significatifs
- Documenter les décisions dans le changelog et la doc - Documenter les décisions dans le changelog et la doc
- Si contrôle local complet: activer `CI_SKIP=true` côté dépôt pour ne pas consommer la CI; ajouter au besoin `[skip ci]` dans les commits automatisés

View File

@ -3,9 +3,25 @@
## Variables denvironnement (CI) ## Variables denvironnement (CI)
- Secrets CI uniquement (pas de secrets en clair) - Secrets CI uniquement (pas de secrets en clair)
- Variables agents : OPENAI_API_KEY, OPENAI_MODEL, OPENAI_API_BASE, OPENAI_TEMPERATURE - **Agents IA**: `OPENAI_API_KEY`, `OPENAI_MODEL`, `OPENAI_API_BASE`, `OPENAI_TEMPERATURE`
- Secret release: RELEASE_TOKEN (publication des releases via lAPI Gitea) - **Release**: `RELEASE_TOKEN` (publication des releases via lAPI Gitea)
- Variable optionnelle: BASE_URL (ex: `https://git.4nkweb.com`) - **Forge**: `BASE_URL` (ex: `https://git.4nkweb.com`)
- **Runner unifié**:
- `RUNNER_MODE` = `agents` | `runner` | `both` (par défaut: `agents`)
- `REGISTRATION_TOKEN` (requis si `RUNNER_MODE=runner` ou `both` sans config existante)
- **Flag de gel CI**:
- `CI_SKIP` (défaut `true` dans le template): quand `true`, les jobs CI sont courtcircuités
- Définir à `false` pour réactiver la CI côté dépôt
- Alternative ponctuelle: commit message `[skip ci]`
## Variables denvironnement (agents)
- `AUTO_FIX` (0/1, défaut 0): active les corrections automatiques côté agents
- Création de la structure `tests/**` manquante
- Génération de squelettes minimalistes pour certains fichiers de `docs/`
- `SCOPE` (`all`|`changed`, défaut `all`):
- `all`: passe sur lensemble du dépôt
- `changed`: focalise les contrôles/corrections sur les fichiers modifiés du dernier commit
## Conventions ## Conventions
@ -17,6 +33,21 @@
- bash requis (job CI `bash-required`) - bash requis (job CI `bash-required`)
- Fallback PowerShell utilisable localement - Fallback PowerShell utilisable localement
## Conteneur unifié (runner+agents)
- Image: construite via `docker/Dockerfile.ci`, orchestrée par `docker-compose.ci.yml`
- Montage: le projet courant est monté sur `/work`, les rapports dans `/work/tests/reports/agents`
- Secrets locaux: `~/.4nk_template/.env` monté en lecture seule dans le conteneur
Variables utilisées par lentrypoint `docker/entrypoint.ci.sh`:
- `RUNNER_MODE` détermine le mode dexécution
- `BASE_URL` et `REGISTRATION_TOKEN` servent à lenregistrement du runner (act_runner)
## Commit message — désactiver la CI ponctuellement
- Ajouter `[skip ci]` au message de commit pour ignorer un run côté Gitea Actions
## Gestion locale des secrets (~/.4nk_template/.env) ## Gestion locale des secrets (~/.4nk_template/.env)
- Modèle fourni: `scripts/env/.env.template` (clés sans valeurs) - Modèle fourni: `scripts/env/.env.template` (clés sans valeurs)

View File

@ -47,3 +47,25 @@ bash scripts/deploy/setup.sh git@host:org/mon-projet.git --dest ~/work --force
- Vérification santé/logs/dashboards - Vérification santé/logs/dashboards
- Suivi des erreurs et retours - Suivi des erreurs et retours
## Conteneur unifié (runner + agents)
- Build:
```bash
docker compose -f docker-compose.ci.yml build
```
- Exécuter les agents sur le dépôt courant:
```bash
docker compose -f docker-compose.ci.yml up --abort-on-container-exit
# Rapports: tests/reports/agents/*.md
```
- Lancer le runner dans le conteneur unifié:
```bash
export RUNNER_MODE=runner BASE_URL="https://git.4nkweb.com" REGISTRATION_TOKEN="<token>"
docker compose -f docker-compose.ci.yml up -d
```

View File

@ -25,15 +25,17 @@
### Runner Gitea (labels) ### Runner Gitea (labels)
- Configurez votre runner avec labels: `self-hosted,linux` - Configurez votre runner avec labels: `self-hosted,linux`
- Exemple (act_runner): - Option A (runner dédié): `gitea/act_runner` via docker-compose dans `runner/`
- Enregistrement: `./act_runner register --labels "self-hosted,linux"` - Option B (conteneur unifié): `RUNNER_MODE=runner` dans `docker-compose.ci.yml` + `BASE_URL` et `REGISTRATION_TOKEN`
- Service: définissez `RUNNER_LABELS="self-hosted,linux"` - Enregistrement (automatisé par entrypoint si variables présentes)
- Démarrage: `docker compose -f docker-compose.ci.yml up -d`
## 4. Workflows requis ## 4. Workflows requis
- `code-quality`, `unit-tests`, `documentation-tests`, `security-audit` - `code-quality`, `unit-tests`, `documentation-tests`, `security-audit`
- `deployment-checks`, `bash-required`, `markdownlint`, `release-guard`, `release-create` - `deployment-checks`, `bash-required`, `markdownlint`, `release-guard`, `release-create`
- (Optionnels) `agents-smoke`, `openia-agents` - (Optionnels) `agents-smoke`, `openia-agents`
- (Conteneur unifié) job custom pour builder et lancer `docker-compose.ci.yml` si nécessaire
## 5. Processus PR ## 5. Processus PR

View File

@ -16,6 +16,23 @@
- Tagging: `vX.Y.Z` ou `vX.Y.Z-wip.N` - Tagging: `vX.Y.Z` ou `vX.Y.Z-wip.N`
- Notes de release (résumé, changements majeurs, impacts) - Notes de release (résumé, changements majeurs, impacts)
### Stratégies de merge (tags → branches cibles)
- Tag sur `main` (latest):
- Aligner `TEMPLATE_VERSION` et `CHANGELOG.md` sur la branche de travail
- Taguer `vX.Y.Z` puis merger la branche (PR) vers `main`
- Si flux local (CI désactivée): appliquer les agents en local avant tag/push
- Tag sur `develop` (prérelease/wip):
- Utiliser `vX.Y.Z-wip.N` pour itérer
- Merger régulièrement vers `develop`; rebase/merge planifié vers `main` pour la release finale
### Cas particuliers
- Merge de tag existant vers `main` ou `develop`:
- Créer une PR contenant lalignement version/changelog correspondant au tag
- Appliquer les agents (localement si CI neutre) puis merger
## Postlancement ## Postlancement
- Suivi issues/retours - Suivi issues/retours

View File

@ -15,6 +15,25 @@ Ce document explique comment utiliser le template pour initier, documenter, cont
3) Tenir `docs/INDEX.md` et `CHANGELOG.md` à jour 3) Tenir `docs/INDEX.md` et `CHANGELOG.md` à jour
4) Activer les workflows CI et vérifier `release-guard`/`security-audit` 4) Activer les workflows CI et vérifier `release-guard`/`security-audit`
## 2.1 Intégrer 4NK_template dans un projet existant
```bash
# Depuis le dépôt 4NK_template
bash scripts/deploy/setup.sh <git_url_du_projet> [--dest DIR] [--force]
# Compléter ensuite ~/.4nk_template/.env si nécessaire (OPENAI_*, BASE_URL, RELEASE_TOKEN)
```
### Intégration via Docker (recommandé)
```bash
# Build limage unifiée
docker compose -f docker-compose.ci.yml build
# Appliquer le template depuis le conteneur (monter le repo projet sur /host)
docker run --rm -v "$PWD":/work -v "/chemin/vers/projet":/host 4nk-template-ci:latest \
bash -lc "/work/scripts/deploy/setup.sh file:///host/.git --dest /host"
```
## 3. Documentation ## 3. Documentation
- Utiliser les squelettes de `docs/templates/**` comme base - Utiliser les squelettes de `docs/templates/**` comme base
@ -25,9 +44,74 @@ Ce document explique comment utiliser le template pour initier, documenter, cont
- Recommandé (bash): `scripts/agents/run.sh [target_dir] [output_dir] [agent]` - Recommandé (bash): `scripts/agents/run.sh [target_dir] [output_dir] [agent]`
- Windows fallback: `scripts/agents/run.ps1 -TargetDir . -OutputDir tests/reports/agents -Agent <nom>` - Windows fallback: `scripts/agents/run.ps1 -TargetDir . -OutputDir tests/reports/agents -Agent <nom>`
- Rapports: `tests/reports/agents/*.md` - Conteneur (option): `docker compose -f docker-compose.ci.yml up --abort-on-container-exit`
- Rapports: `tests/reports/agents/*.md`
- Variables utiles: `RUNNER_MODE`, `BASE_URL`, `REGISTRATION_TOKEN`
- Script helper: `scripts/dev/run_project_ci.sh`
- Autocorrections: `AUTO_FIX=1` pour créer la structure de tests et des squelettes docs
## 5. Remplacer la CI par une exécution locale (recommandé)
- CI neutre par défaut: `CI_SKIP=true` dans le workflow; réactivez en le passant à `false` côté dépôt.
- Commits: contrôles rapides avant commit
```bash
npx -y markdownlint-cli "**/*.md" --ignore "archive/**"
AUTO_FIX=1 SCOPE=changed scripts/agents/run.sh
# Ajoutez [skip ci] dans le message de commit pour éviter les runs distants
```
- Push: contrôles complets prépush
```bash
AUTO_FIX=1 SCOPE=all scripts/agents/run.sh
bash scripts/security/audit.sh || true
# Si outillage présent (exemples): cargo check / go vet / npx eslint / tsc --noEmit / ruff…
bash scripts/release/guard.sh || true
```
- Release locale (puis push tag)
```bash
echo "vYYYY.MM.P" > TEMPLATE_VERSION
git add TEMPLATE_VERSION CHANGELOG.md
git commit -m "[skip ci] chore(release): vYYYY.MM.P"
git tag -a vYYYY.MM.P -m "release: vYYYY.MM.P (latest)"
git push && git push origin vYYYY.MM.P
```
### Hooks conseillés
`.git/hooks/pre-commit`:
```bash
#!/usr/bin/env bash
set -e
npx -y markdownlint-cli "**/*.md" --ignore "archive/**"
AUTO_FIX=1 SCOPE=changed scripts/agents/run.sh
```
`.git/hooks/pre-push`:
```bash
#!/usr/bin/env bash
set -e
AUTO_FIX=1 SCOPE=all scripts/agents/run.sh
bash scripts/security/audit.sh || true
bash scripts/release/guard.sh || true
```
Ou installez-les automatiquement:
```bash
bash scripts/local/install_hooks.sh
```
- Agents utiles en premier passage: `documentation`, `quality-technique`, `open-source`, `securite`, `deploiement` - Agents utiles en premier passage: `documentation`, `quality-technique`, `open-source`, `securite`, `deploiement`
### Script de merge local (main/develop)
```bash
# Merge de la branche courante vers main (valide localement avant)
bash scripts/local/merge_branch.sh main
# Merge vers develop
bash scripts/local/merge_branch.sh develop
```
## 5. Qualité et CI ## 5. Qualité et CI
- Jobs attendus: qualité, tests (catégories pertinentes), documentation, securityaudit, bashrequired, releaseguard - Jobs attendus: qualité, tests (catégories pertinentes), documentation, securityaudit, bashrequired, releaseguard

49
runner/README.md Normal file
View File

@ -0,0 +1,49 @@
# Runner Gitea (act_runner)
Ce dossier contient une configuration prête à l'emploi pour exécuter un runner Gitea via Docker Compose.
## Prérequis
- Hôte Linux avec Docker et Docker Compose
- URL de l'instance Gitea et un token d'enregistrement (repo/org/instance)
## Configuration
- Le runner lit un fichier .env GLOBAL: `$HOME/4nk_template/.env` (commun à tous les dépôts)
- Variables attendues dans ce fichier:
- `INSTANCE_URL` (ex: `https://git.4nkweb.com`)
- `REGISTRATION_TOKEN` (token d'enregistrement)
- `RUNNER_NAME` (optionnel)
- `RUNNER_LABELS` (optionnel, défaut: `self-hosted,linux`)
- Aucun `.env` local dans `runner/` nest nécessaire.
Exemple de contenu minimal:
```dotenv
INSTANCE_URL=https://git.4nkweb.com
REGISTRATION_TOKEN=...
RUNNER_NAME=$(hostname)-runner
RUNNER_LABELS=self-hosted,linux
```
## Démarrage
```bash
cd runner
docker compose up -d
```
Le runner s'enregistre automatiquement et apparaît dans Settings → Actions → Runners.
## Arrêt / Mise à jour
```bash
docker compose down
# Mise à jour d'image
docker compose pull && docker compose up -d
```
## Mode éphémère (optionnel)
Activez `GITEA_RUNNER_EPHEMERAL=1` dans `docker-compose.yml` pour des runners jetables.
Réf: Gitea Act Runner — https://docs.gitea.com/usage/actions/act-runner

18
runner/docker-compose.yml Normal file
View File

@ -0,0 +1,18 @@
version: "3.8"
services:
runner:
image: docker.io/gitea/act_runner:nightly
container_name: gitea-act-runner
restart: unless-stopped
env_file:
- ${USERPROFILE}/.4nk_template/.env
environment:
- GITEA_RUNNER_LABELS=${RUNNER_LABELS:-self-hosted,linux}
- GITEA_RUNNER_NAME=${RUNNER_NAME:-local-runner}
- GITEA_INSTANCE_URL=${INSTANCE_URL}
- GITEA_RUNNER_REGISTRATION_TOKEN=${REGISTRATION_TOKEN}
# Uncomment to enable ephemeral mode
# - GITEA_RUNNER_EPHEMERAL=1
volumes:
- ./data:/data
- /var/run/docker.sock:/var/run/docker.sock

View File

@ -4,6 +4,14 @@ set -euo pipefail
# Utilitaire générique pour appeler l'API OpenAI Chat Completions. # Utilitaire générique pour appeler l'API OpenAI Chat Completions.
# Prérequis: variable d'environnement OPENAI_API_KEY et curl. # Prérequis: variable d'environnement OPENAI_API_KEY et curl.
# Chargement env utilisateur (~/.4nk_template/.env) pour exécutions locales/CI docke
"$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/env/ensure_env.sh" || true
if [[ -f "${HOME}/.4nk_template/.env" ]]; then
set -a
. "${HOME}/.4nk_template/.env"
set +a
fi
for bin in curl jq; do for bin in curl jq; do
if ! command -v "$bin" >/dev/null 2>&1; then if ! command -v "$bin" >/dev/null 2>&1; then
echo "$bin manquant. Installez $bin." >&2 echo "$bin manquant. Installez $bin." >&2

19
scripts/agents/common.sh Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
# Portée des contrôles: all (défaut) ou changed
export SCOPE="${SCOPE:-all}"
list_changed_paths() {
# Renvoie la liste des chemins modifiés (HEAD~1..HEAD), ou vide si non dispo
git diff --name-only HEAD~1..HEAD 2>/dev/null || true
}
is_path_changed() {
local path="$1"
if [[ "$SCOPE" != "changed" ]]; then return 0; fi
local changed
changed=$(list_changed_paths)
if [[ -z "$changed" ]]; then return 0; fi
grep -q "^${path%/}\(/\|$\)" <<<"$changed" && return 0 || return 1
}

View File

@ -5,22 +5,28 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/compilation_agent.md" SUMMARY_FILE="$OUTPUT_DIR/compilation_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Compilation" > "$SUMMARY_FILE" echo "# Agent Compilation" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(.gitea/workflows/ci.yml)
any=0; for p in "${relevant[@]}"; do if is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement compilation CI (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
if grep -q "cargo" .gitea/workflows/ci.yml 2>/dev/null; then if grep -q "cargo" .gitea/workflows/ci.yml 2>/dev/null; then
echo "- Étapes de build/format/clippy Rust détectées dans la CI." >> "$SUMMARY_FILE" echo "- Étapes de build/format/clippy Rust détectées dans la CI." >> "$SUMMARY_FILE"
else else
echo "- Étapes de compilation non détectées dans la CI (à ajouter si nécessaire)." >> "$SUMMARY_FILE" echo "- Étapes de compilation non détectées dans la CI (à ajouter si nécessaire)." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Précise une cadence de compilation (avant refactor/push, après update deps) et les conditions de blocage si erreurs. Précise une cadence de compilation (avant refactor/push, après update deps) et les conditions de blocage si erreurs.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,21 +5,27 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/dependances_agent.md" SUMMARY_FILE="$OUTPUT_DIR/dependances_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Dépendances" > "$SUMMARY_FILE" echo "# Agent Dépendances" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
echo "- Vérifier régulièrement les dépendances (audit sécurité, mises à jour stables)." >> "$SUMMARY_FILE" echo "- Vérifier régulièrement les dépendances (audit sécurité, mises à jour stables)." >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(package.json package-lock.json pnpm-lock.yaml yarn.lock requirements.txt pyproject.toml Cargo.toml go.mod .gitea/workflows/ci.yml)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement dépendances/CI (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
if grep -q "security-audit" .gitea/workflows/ci.yml 2>/dev/null; then if grep -q "security-audit" .gitea/workflows/ci.yml 2>/dev/null; then
echo "- Job CI security-audit détecté." >> "$SUMMARY_FILE" echo "- Job CI security-audit détecté." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Établis une politique de dépendances: ajout automatique si justifié, vérification des dernières versions stables, documentation des impacts (ARCHITECTURE, CONFIGURATION, CHANGELOG), et rollback. Établis une politique de dépendances: ajout automatique si justifié, vérification des dernières versions stables, documentation des impacts (ARCHITECTURE, CONFIGURATION, CHANGELOG), et rollback.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,11 +5,17 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/deployment_agent.md" SUMMARY_FILE="$OUTPUT_DIR/deployment_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Déploiement" > "$SUMMARY_FILE" echo "# Agent Déploiement" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(docs/DEPLOYMENT.md docs/RELEASE_PLAN.md .gitea/workflows/ci.yml)
any=0; for p in "${relevant[@]}"; do if is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
echo "## Résultats locaux" >> "$SUMMARY_FILE" echo "## Résultats locaux" >> "$SUMMARY_FILE"
ok=1 ok=1
for f in docs/DEPLOYMENT.md docs/RELEASE_PLAN.md .gitea/workflows/ci.yml; do for f in docs/DEPLOYMENT.md docs/RELEASE_PLAN.md .gitea/workflows/ci.yml; do
@ -17,11 +23,11 @@ for f in docs/DEPLOYMENT.md docs/RELEASE_PLAN.md .gitea/workflows/ci.yml; do
done done
if [[ $ok -eq 1 ]]; then echo "- Prérequis documentaires présents." >> "$SUMMARY_FILE"; fi if [[ $ok -eq 1 ]]; then echo "- Prérequis documentaires présents." >> "$SUMMARY_FILE"; fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Établis une checklist de déploiement minimale (préchecks, variables, smoke tests, rollback, postdeploy) adaptée à un template CI Gitea. Établis une checklist de déploiement minimale (préchecks, variables, smoke tests, rollback, postdeploy) adaptée à un template CI Gitea.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -16,11 +16,11 @@ else
echo "- Aucun fichier de dérogations locales détecté." >> "$SUMMARY_FILE" echo "- Aucun fichier de dérogations locales détecté." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Définis un format pour enregistrer les dérogations (path, raison, propriétaire, échéance), tolérance CI, et revue périodique. Définis un format pour enregistrer les dérogations (path, raison, propriétaire, échéance), tolérance CI, et revue périodique.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,6 +5,7 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/documentation_agent.md" SUMMARY_FILE="$OUTPUT_DIR/documentation_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Documentation" > "$SUMMARY_FILE" echo "# Agent Documentation" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
@ -20,13 +21,32 @@ if ((${#missing[@]}==0)); then
else else
echo "- Fichiers manquants:" >> "$SUMMARY_FILE" echo "- Fichiers manquants:" >> "$SUMMARY_FILE"
for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done
if [[ "${AUTO_FIX:-0}" == "1" ]]; then
echo >> "$SUMMARY_FILE"
echo "## Autocorrections" >> "$SUMMARY_FILE"
for m in "${missing[@]}"; do
case "$m" in
docs/INDEX.md)
mkdir -p docs && printf "# Index\n\n" > "$m" && echo "- Créé squelette: $m" >> "$SUMMARY_FILE" ;;
docs/ARCHITECTURE.md)
mkdir -p docs && printf "# Architecture\n\n" > "$m" && echo "- Créé squelette: $m" >> "$SUMMARY_FILE" ;;
docs/TESTING.md)
mkdir -p docs && printf "# Tests\n\n" > "$m" && echo "- Créé squelette: $m" >> "$SUMMARY_FILE" ;;
docs/SECURITY_AUDIT.md)
mkdir -p docs && printf "# Security Audit\n\n" > "$m" && echo "- Créé squelette: $m" >> "$SUMMARY_FILE" ;;
docs/DEPLOYMENT.md)
mkdir -p docs && printf "# Déploiement\n\n" > "$m" && echo "- Créé squelette: $m" >> "$SUMMARY_FILE" ;;
*) : ;;
esac
done
fi
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Élabore une liste courte daméliorations documentation (INDEX à jour, traçabilité changes ↔ CHANGELOG, sections sécurité/tests/déploiement). Élabore une liste courte daméliorations documentation (INDEX à jour, traçabilité changes ↔ CHANGELOG, sections sécurité/tests/déploiement).
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -19,11 +19,11 @@ else
echo "- Utiliser docx2txt pour extraction et documenter dans docs/INDEX.md" >> "$SUMMARY_FILE" echo "- Utiliser docx2txt pour extraction et documenter dans docs/INDEX.md" >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Décris une procédure standard de traitement des .docx (docx2txt, import, traçabilité dans docs/INDEX.md) et les risques à éviter. Décris une procédure standard de traitement des .docx (docx2txt, import, traçabilité dans docs/INDEX.md) et les risques à éviter.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -18,11 +18,11 @@ else
echo "$csvs" | sed 's/^/ - /' >> "$SUMMARY_FILE" echo "$csvs" | sed 's/^/ - /' >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
À partir des CSV présents (entêtes multilignes possibles), propose une méthode pour définir toutes les colonnes, types et validations, et pointer vers les docs à mettre à jour (API, ARCHITECTURE, USAGE). À partir des CSV présents (entêtes multilignes possibles), propose une méthode pour définir toutes les colonnes, types et validations, et pointer vers les docs à mettre à jour (API, ARCHITECTURE, USAGE).
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -18,11 +18,11 @@ done
if [[ $issues -eq 0 ]]; then echo "- Conformité éditoriale de base: OK (présence des fichiers clés)." >> "$SUMMARY_FILE"; fi if [[ $issues -eq 0 ]]; then echo "- Conformité éditoriale de base: OK (présence des fichiers clés)." >> "$SUMMARY_FILE"; fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Évalue la conformité éditoriale (français, pas dexemples applicatifs, intro/conclusion) et liste 5 actions damélioration priorisées. Évalue la conformité éditoriale (français, pas dexemples applicatifs, intro/conclusion) et liste 5 actions damélioration priorisées.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,16 +5,22 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/frontend_agent.md" SUMMARY_FILE="$OUTPUT_DIR/frontend_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Frontend" > "$SUMMARY_FILE" echo "# Agent Frontend" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Définis des principes front: code splitting (React.lazy/Suspense), centralisation détat (Redux/Context), abstraction des services, et tests associés. Définis des principes front: code splitting (React.lazy/Suspense), centralisation détat (Redux/Context), abstraction des services, et tests associés.
P EOF
) )
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true if [[ "$SCOPE" == "changed" ]]; then
relevant=(package.json tsconfig.json src/)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement frontend pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,11 +5,17 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/gitea_agent.md" SUMMARY_FILE="$OUTPUT_DIR/gitea_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Gitea" > "$SUMMARY_FILE" echo "# Agent Gitea" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(.gitea/ISSUE_TEMPLATE/bug_report.md .gitea/ISSUE_TEMPLATE/feature_request.md .gitea/PULL_REQUEST_TEMPLATE.md .gitea/workflows/ci.yml)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement Gitea pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
need=(.gitea/ISSUE_TEMPLATE/bug_report.md .gitea/ISSUE_TEMPLATE/feature_request.md .gitea/PULL_REQUEST_TEMPLATE.md .gitea/workflows/ci.yml) need=(.gitea/ISSUE_TEMPLATE/bug_report.md .gitea/ISSUE_TEMPLATE/feature_request.md .gitea/PULL_REQUEST_TEMPLATE.md .gitea/workflows/ci.yml)
missing=() missing=()
for f in "${need[@]}"; do [[ -f "$f" ]] || missing+=("$f"); done for f in "${need[@]}"; do [[ -f "$f" ]] || missing+=("$f"); done
@ -20,11 +26,11 @@ else
echo "- Manquants:" >> "$SUMMARY_FILE"; for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done echo "- Manquants:" >> "$SUMMARY_FILE"; for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Propose des vérifications CI additionnelles Gitea (lint, tests, sécurité, scripts exécutables) et notifications en cas déchecs. Propose des vérifications CI additionnelles Gitea (lint, tests, sécurité, scripts exécutables) et notifications en cas déchecs.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,11 +5,17 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/open_source_agent.md" SUMMARY_FILE="$OUTPUT_DIR/open_source_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Open Source" > "$SUMMARY_FILE" echo "# Agent Open Source" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(LICENSE CONTRIBUTING.md CODE_OF_CONDUCT.md docs/OPEN_SOURCE_CHECKLIST.md)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement open source pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
need=(LICENSE CONTRIBUTING.md CODE_OF_CONDUCT.md docs/OPEN_SOURCE_CHECKLIST.md) need=(LICENSE CONTRIBUTING.md CODE_OF_CONDUCT.md docs/OPEN_SOURCE_CHECKLIST.md)
missing=() missing=()
for f in "${need[@]}"; do [[ -f "$f" ]] || missing+=("$f"); done for f in "${need[@]}"; do [[ -f "$f" ]] || missing+=("$f"); done
@ -20,11 +26,11 @@ else
echo "- Manquants:" >> "$SUMMARY_FILE"; for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done echo "- Manquants:" >> "$SUMMARY_FILE"; for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Propose une checklist pour préparer louverture open source (gouvernance, CI, sécurité, documentation) compatible avec Gitea. Propose une checklist pour préparer louverture open source (gouvernance, CI, sécurité, documentation) compatible avec Gitea.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -16,11 +16,11 @@ else
echo "- Dossier tests/performance manquant." >> "$SUMMARY_FILE" echo "- Dossier tests/performance manquant." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Propose un plan minimal de tests de performance reproductibles (outillage, métriques, critères de succès) et archivage des rapports. Propose un plan minimal de tests de performance reproductibles (outillage, métriques, critères de succès) et archivage des rapports.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -1,6 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Chargement env utilisateur (~/.4nk_template/.env)
"$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/env/ensure_env.sh" || true
if [[ -f "${HOME}/.4nk_template/.env" ]]; then
set -a
. "${HOME}/.4nk_template/.env"
set +a
fi
TARGET_DIR="${1:-.}" TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
@ -21,11 +29,11 @@ if [[ $issues -eq 0 ]]; then
echo "- Aucun problème formel bloquant détecté." >> "$SUMMARY_FILE" echo "- Aucun problème formel bloquant détecté." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Évalue la qualité formelle (français uniquement, typographie, absence dexemples applicatifs, intro/conclusion) et propose 5 recommandations priorisées. Évalue la qualité formelle (français uniquement, typographie, absence dexemples applicatifs, intro/conclusion) et propose 5 recommandations priorisées.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -1,6 +1,17 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Chargement env utilisateur (~/.4nk_template/.env)
"$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/env/ensure_env.sh" || true
if [[ -f "${HOME}/.4nk_template/.env" ]]; then
set -a
. "${HOME}/.4nk_template/.env"
set +a
fi
# Portée (all|changed)
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
TARGET_DIR="${1:-.}" TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
@ -74,11 +85,11 @@ if [[ "$HAS_SHELL_PWSH" -eq 1 && "$HAS_PWSH" -eq 1 ]]; then
fi fi
# IA (optionnelle) # IA (optionnelle)
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Analyse la conformité qualité technique du dépôt selon AGENTS.md et la CI. Priorise: lint/format/type-check, structure de tests, cohérence docs/CI, sécurité basique. Propose 5 actions concrètes. Analyse la conformité qualité technique du dépôt selon AGENTS.md et la CI. Priorise: lint/format/type-check, structure de tests, cohérence docs/CI, sécurité basique. Propose 5 actions concrètes.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -16,11 +16,11 @@ else
echo "- Dossier archive/ manquant (recommandé pour REX)." >> "$SUMMARY_FILE" echo "- Dossier archive/ manquant (recommandé pour REX)." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Décris la boucle de triage complète (repro minimale, logs, bissection, hypothèses, tests ciblés, correctif, nonrégression) et quand produire un REX. Décris la boucle de triage complète (repro minimale, logs, bissection, hypothèses, tests ciblés, correctif, nonrégression) et quand produire un REX.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -1,140 +0,0 @@
Param(
[string]$TargetDir='.',
[string]$OutputDir='tests/reports/agents',
[string]$Agent='all'
)
$bashOk = $false
try {
& bash -lc 'echo ok' | Out-Null
if ($LASTEXITCODE -eq 0) { $bashOk = $true }
} catch {}
if ($bashOk) {
& bash "scripts/agents/run.sh" $TargetDir $OutputDir $Agent
exit $LASTEXITCODE
}
# Fallback PowerShell (best-effort) lorsque bash n'est pas disponible
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
function Write-Report($name, $lines) {
$file = Join-Path $OutputDir $name
$lines | Out-File -FilePath $file -Encoding UTF8 -Force
Write-Host "Rapport: $file"
}
Set-Location $TargetDir
switch ($Agent) {
'documentation' {
$missing = @()
$required = @('docs/INDEX.md','docs/project/INDEX.md','docs/templates/INDEX.md')
foreach ($f in $required) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Documentation', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Documentation essentielle présente.' }
else { $content += '- Fichiers manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'documentation_agent.md' $content
}
'tests' {
$need = @('tests/unit','tests/integration','tests/connectivity','tests/external','tests/performance','tests/logs','tests/reports')
$missing = @(); foreach ($d in $need) { if (-not (Test-Path $d)) { $missing += $d } }
$content = @('# Agent Tests', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Structure de tests conforme.' } else { $content += '- Dossiers manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'tests_agent.md' $content
}
'performance' {
$content = @('# Agent Performance', '', '## Résultats (fallback PowerShell)')
if (Test-Path 'tests/performance') { $content += '- tests/performance présent.' } else { $content += '- tests/performance manquant.' }
Write-Report 'performance_agent.md' $content
}
'quality-technique' {
$missing = @()
$required = @('README.md','LICENSE','CONTRIBUTING.md','CODE_OF_CONDUCT.md','CHANGELOG.md','.gitea/workflows/ci.yml')
foreach ($f in $required) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Qualité technique', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Fichiers de base présents.' }
else { $content += '- Fichiers manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'quality_tech.md' $content
}
'open-source' {
$missing = @()
$required = @('LICENSE','CONTRIBUTING.md','CODE_OF_CONDUCT.md','docs/OPEN_SOURCE_CHECKLIST.md')
foreach ($f in $required) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Open Source', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Prérequis open source présents.' }
else { $content += '- Manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'open_source_agent.md' $content
}
'securite' {
$missing = @(); foreach ($f in @('docs/SECURITY_AUDIT.md','.gitea/workflows/ci.yml')) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Sécurité', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Socle sécurité et CI présents.' } else { $content += '- Manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'security_agent.md' $content
}
'deploiement' {
$missing = @(); foreach ($f in @('docs/DEPLOYMENT.md','.gitea/workflows/ci.yml')) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Déploiement', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Documentation et CI de déploiement présentes (à valider).' } else { $content += '- Manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'deployment_agent.md' $content
}
'dependances' {
$content = @('# Agent Dépendances', '', '## Résultats (fallback PowerShell)','- Politique à documenter dans ARCHITECTURE/CONFIGURATION/CHANGELOG')
Write-Report 'dependances_agent.md' $content
}
'compilation' {
$content = @('# Agent Compilation', '', '## Résultats (fallback PowerShell)')
if (Test-Path '.gitea/workflows/ci.yml') { $content += '- Étapes de build à vérifier dans la CI.' } else { $content += '- CI absente.' }
Write-Report 'compilation_agent.md' $content
}
'resolution' {
$content = @('# Agent Résolution', '', '## Résultats (fallback PowerShell)')
if (Test-Path 'archive') { $content += '- Dossier archive/ présent pour REX.' } else { $content += '- Dossier archive/ manquant.' }
Write-Report 'resolution_agent.md' $content
}
'ssh-scripts' {
$found = @(); $paths = @('scripts/auto-ssh-push.sh','scripts/init-ssh-env.sh','scripts/setup-ssh-ci.sh','scripts/scripts/auto-ssh-push.sh','scripts/scripts/init-ssh-env.sh','scripts/scripts/setup-ssh-ci.sh')
foreach ($p in $paths) { if (Test-Path $p) { $found += $p } }
$content = @('# Agent SSH & scripts', '', '## Résultats (fallback PowerShell)')
if ($found.Count -gt 0) { $content += '- Scripts trouvés:'; $found | ForEach-Object { $content += " - $_" } } else { $content += '- Aucun script standard détecté.' }
if (Test-Path 'docs/SSH_UPDATE.md') { $content += '- docs/SSH_UPDATE.md présent.' }
Write-Report 'ssh_scripts_agent.md' $content
}
'frontend' {
$content = @('# Agent Frontend', '', '## Résultats (fallback PowerShell)','- Vérifier code splitting, état centralisé, abstraction services (si frontend présent).')
Write-Report 'frontend_agent.md' $content
}
'gitea' {
$need = @('.gitea/ISSUE_TEMPLATE/bug_report.md','.gitea/ISSUE_TEMPLATE/feature_request.md','.gitea/PULL_REQUEST_TEMPLATE.md','.gitea/workflows/ci.yml')
$missing = @(); foreach ($f in $need) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Gitea', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- Configuration Gitea présente.' } else { $content += '- Manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'gitea_agent.md' $content
}
'versionnage' {
$missing = @(); foreach ($f in @('CHANGELOG.md','TEMPLATE_VERSION')) { if (-not (Test-Path $f)) { $missing += $f } }
$content = @('# Agent Versionnage', '', '## Résultats (fallback PowerShell)')
if ($missing.Count -eq 0) { $content += '- CHANGELOG et TEMPLATE_VERSION présents.' } else { $content += '- Manquants:'; $missing | ForEach-Object { $content += " - $_" } }
Write-Report 'versionnage_agent.md' $content
}
'sync-template' {
$content = @('# Agent Synchronisation de template', '', '## Résultats (fallback PowerShell)')
if (Test-Path '.gitea/workflows/template-sync.yml') { $content += '- Workflow template-sync présent.' } else { $content += '- Workflow template-sync manquant.' }
if (Test-Path '.4nk-sync.yml') { $content += '- Manifeste .4nk-sync.yml présent.' } else { $content += '- Manifeste .4nk-sync.yml manquant.' }
Write-Report 'sync_template_agent.md' $content
}
'derogations-locales' {
$content = @('# Agent Dérogations locales', '', '## Résultats (fallback PowerShell)')
if ((Test-Path 'LOCAL_OVERRIDES.yml') -or (Test-Path '.gitea/workflows/LOCAL_OVERRIDES.yml')) { $content += '- Fichier de dérogations détecté.' } else { $content += '- Aucun fichier de dérogations détecté.' }
Write-Report 'derogations_locales_agent.md' $content
}
'all' {
foreach ($a in @('documentation','tests','performance','quality-technique','open-source','securite','deploiement','dependances','compilation','resolution','ssh-scripts','frontend','gitea','versionnage','sync-template','derogations-locales')) {
& $PSCommandPath -TargetDir $TargetDir -OutputDir $OutputDir -Agent $a
}
}
default {
Write-Error "Agent inconnu (fallback): $Agent"; exit 2
}
}
exit 0

View File

@ -26,6 +26,7 @@ Agents:
Frontend: frontend Frontend: frontend
Open source et CI: open-source, gitea, versionnage, securite, deploiement Open source et CI: open-source, gitea, versionnage, securite, deploiement
Synchronisation: sync-template, derogations-locales Synchronisation: sync-template, derogations-locales
Runner: runne
all all
Par défaut: all Par défaut: all
USAGE USAGE
@ -34,6 +35,8 @@ USAGE
AGENT="${3:-all}" AGENT="${3:-all}"
case "$AGENT" in case "$AGENT" in
runner)
"$DIR/runner_agent.sh" "$TARGET_DIR" "$OUTPUT_DIR" ;;
quality-tech|qualite-technique) quality-tech|qualite-technique)
"$DIR/quality_tech.sh" "$TARGET_DIR" "$OUTPUT_DIR" ;; "$DIR/quality_tech.sh" "$TARGET_DIR" "$OUTPUT_DIR" ;;
qualite-formelle|fondation) qualite-formelle|fondation)
@ -75,6 +78,7 @@ case "$AGENT" in
derogations-locales) derogations-locales)
"$DIR/derogations_locales_agent.sh" "$TARGET_DIR" "$OUTPUT_DIR" ;; "$DIR/derogations_locales_agent.sh" "$TARGET_DIR" "$OUTPUT_DIR" ;;
all) all)
"$DIR/runner_agent.sh" "$TARGET_DIR" "$OUTPUT_DIR" || true
"$DIR/quality_tech.sh" "$TARGET_DIR" "$OUTPUT_DIR" "$DIR/quality_tech.sh" "$TARGET_DIR" "$OUTPUT_DIR"
"$DIR/qualite_formelle.sh" "$TARGET_DIR" "$OUTPUT_DIR" "$DIR/qualite_formelle.sh" "$TARGET_DIR" "$OUTPUT_DIR"
"$DIR/fondation_agent.sh" "$TARGET_DIR" "$OUTPUT_DIR" || true "$DIR/fondation_agent.sh" "$TARGET_DIR" "$OUTPUT_DIR" || true

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail
TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "${OUTPUT_DIR}"
report="${OUTPUT_DIR}/runner_agent.md"
echo "# Agent Runner" >"${report}"
echo >>"${report}"
if ! command -v docker >/dev/null 2>&1; then
echo "- Docker non détecté sur l'hôte. Impossible de gérer le runner." >>"${report}"
exit 0
fi
if [[ -f "runner/docker-compose.yml" ]]; then
(
cd runne
# Démarre (ou met à jour) le runne
docker compose up -d || true
)
echo "- Runner démarré/présent via docker compose (runner/docker-compose.yml)." >>"${report}"
else
echo "- Fichier runner/docker-compose.yml introuvable; aucun démarrage effectué." >>"${report}"
fi
echo "- Rapports: ${report}" >>"${report}"
exit 0

View File

@ -5,11 +5,17 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/security_agent.md" SUMMARY_FILE="$OUTPUT_DIR/security_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Sécurité" > "$SUMMARY_FILE" echo "# Agent Sécurité" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(scripts/security/audit.sh .gitea/workflows/ci.yml docs/SECURITY_AUDIT.md)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement sécurité pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
echo "## Résultats locaux" >> "$SUMMARY_FILE" echo "## Résultats locaux" >> "$SUMMARY_FILE"
if [[ -x scripts/security/audit.sh ]]; then if [[ -x scripts/security/audit.sh ]]; then
if scripts/security/audit.sh >> "$SUMMARY_FILE" 2>&1; then if scripts/security/audit.sh >> "$SUMMARY_FILE" 2>&1; then
@ -21,11 +27,11 @@ else
echo "- scripts/security/audit.sh introuvable ou non exécutable." >> "$SUMMARY_FILE" echo "- scripts/security/audit.sh introuvable ou non exécutable." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
À partir dun dépôt template, propose 5 contrôles sécurité CI/CD additionnels (secrets, permissions, dépendances, scans) et un ordre de priorité. À partir dun dépôt template, propose 5 contrôles sécurité CI/CD additionnels (secrets, permissions, dépendances, scans) et un ordre de priorité.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,11 +5,17 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/ssh_scripts_agent.md" SUMMARY_FILE="$OUTPUT_DIR/ssh_scripts_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent SSH & scripts" > "$SUMMARY_FILE" echo "# Agent SSH & scripts" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(scripts/auto-ssh-push.sh scripts/init-ssh-env.sh scripts/setup-ssh-ci.sh docs/SSH_UPDATE.md)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement SSH/scripts pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
paths=( paths=(
scripts/auto-ssh-push.sh scripts/auto-ssh-push.sh
scripts/init-ssh-env.sh scripts/init-ssh-env.sh
@ -27,11 +33,11 @@ if [[ $found -eq 0 ]]; then echo "- Scripts SSH standard introuvables (vérifier
if [[ -f docs/SSH_UPDATE.md ]]; then echo "- docs/SSH_UPDATE.md présent." >> "$SUMMARY_FILE"; fi if [[ -f docs/SSH_UPDATE.md ]]; then echo "- docs/SSH_UPDATE.md présent." >> "$SUMMARY_FILE"; fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Propose une checklist de conformité SSH (permissions, secrets CI, idempotence, journalisation non sensible) et intégration de contrôles CI. Propose une checklist de conformité SSH (permissions, secrets CI, idempotence, journalisation non sensible) et intégration de contrôles CI.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,11 +5,17 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/structure_agent.md" SUMMARY_FILE="$OUTPUT_DIR/structure_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Structure" > "$SUMMARY_FILE" echo "# Agent Structure" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(docs .gitea scripts CHANGELOG.md AGENTS.md)
any=0; for p in "${relevant[@]}"; do if [[ -e "$p" ]] && is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement structurel pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
need=(docs .gitea scripts CHANGELOG.md AGENTS.md) need=(docs .gitea scripts CHANGELOG.md AGENTS.md)
missing=() missing=()
for p in "${need[@]}"; do [[ -e "$p" ]] || missing+=("$p"); done for p in "${need[@]}"; do [[ -e "$p" ]] || missing+=("$p"); done
@ -21,11 +27,11 @@ else
for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Vérifie lalignement avec larborescence 4NK_node et propose 5 corrections prioritaires (créations/archives/métadonnées) si des écarts sont détectés. Vérifie lalignement avec larborescence 4NK_node et propose 5 corrections prioritaires (créations/archives/métadonnées) si des écarts sont détectés.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -22,11 +22,11 @@ else
echo "- Manifeste .4nk-sync.yml manquant." >> "$SUMMARY_FILE" echo "- Manifeste .4nk-sync.yml manquant." >> "$SUMMARY_FILE"
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Propose une procédure de synchronisation contrôlée (PR dédiée, vérif checksums/manifest_checksum, mise à jour TEMPLATE_VERSION, mise à jour CHANGELOG/INDEX). Propose une procédure de synchronisation contrôlée (PR dédiée, vérif checksums/manifest_checksum, mise à jour TEMPLATE_VERSION, mise à jour CHANGELOG/INDEX).
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -1,10 +1,19 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Chargement env utilisateur (~/.4nk_template/.env)
"$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/env/ensure_env.sh" || true
if [[ -f "${HOME}/.4nk_template/.env" ]]; then
set -a
. "${HOME}/.4nk_template/.env"
set +a
fi
TARGET_DIR="${1:-.}" TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/tests_agent.md" SUMMARY_FILE="$OUTPUT_DIR/tests_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Tests" > "$SUMMARY_FILE" echo "# Agent Tests" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
@ -21,13 +30,21 @@ if ((${#missing[@]}==0)); then
else else
echo "- Dossiers manquants:" >> "$SUMMARY_FILE" echo "- Dossiers manquants:" >> "$SUMMARY_FILE"
for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done for m in "${missing[@]}"; do echo " - $m" >> "$SUMMARY_FILE"; done
if [[ "${AUTO_FIX:-0}" == "1" ]]; then
echo >> "$SUMMARY_FILE"
echo "## Autocorrections" >> "$SUMMARY_FILE"
for m in "${missing[@]}"; do
mkdir -p "$m" && echo "- Créé: $m" >> "$SUMMARY_FILE"
done
mkdir -p tests/reports/agents tests/logs || true
fi
fi fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Propose un plan court pour renforcer la pyramide de tests (unit, integration, connectivity, external, performance) pour ce template, avec 5 actions. Propose un plan court pour renforcer la pyramide de tests (unit, integration, connectivity, external, performance) pour ce template, avec 5 actions.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -5,22 +5,28 @@ TARGET_DIR="${1:-.}"
OUTPUT_DIR="${2:-tests/reports/agents}" OUTPUT_DIR="${2:-tests/reports/agents}"
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
SUMMARY_FILE="$OUTPUT_DIR/versionnage_agent.md" SUMMARY_FILE="$OUTPUT_DIR/versionnage_agent.md"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" || true
echo "# Agent Versionnage" > "$SUMMARY_FILE" echo "# Agent Versionnage" > "$SUMMARY_FILE"
echo >> "$SUMMARY_FILE" echo >> "$SUMMARY_FILE"
pushd "$TARGET_DIR" >/dev/null pushd "$TARGET_DIR" >/dev/null
if [[ "$SCOPE" == "changed" ]]; then
relevant=(CHANGELOG.md TEMPLATE_VERSION)
any=0; for p in "${relevant[@]}"; do if is_path_changed "$p"; then any=1; break; fi; done
if [[ $any -eq 0 ]]; then echo "- Aucun changement versionnage pertinent (SCOPE=changed)." >> "$SUMMARY_FILE"; echo "Rapport: $SUMMARY_FILE"; popd >/dev/null; exit 0; fi
fi
ok=1 ok=1
for f in CHANGELOG.md TEMPLATE_VERSION; do for f in CHANGELOG.md TEMPLATE_VERSION; do
if [[ ! -f "$f" ]]; then echo "- Manquant: $f" >> "$SUMMARY_FILE"; ok=0; fi if [[ ! -f "$f" ]]; then echo "- Manquant: $f" >> "$SUMMARY_FILE"; ok=0; fi
done done
if [[ $ok -eq 1 ]]; then echo "- CHANGELOG et TEMPLATE_VERSION présents." >> "$SUMMARY_FILE"; fi if [[ $ok -eq 1 ]]; then echo "- CHANGELOG et TEMPLATE_VERSION présents." >> "$SUMMARY_FILE"; fi
PROMPT=$(cat <<'P' PROMPT=$(cat <<'EOF'
Décris la procédure dalignement version ↔ changelog ↔ tag git (latest vs wip) et conditions de blocage release. Décris la procédure dalignement version ↔ changelog ↔ tag git (latest vs wip) et conditions de blocage release.
P EOF
) )
"scripts/agents/ai_prompt.sh" "$PROMPT" >> "$SUMMARY_FILE" || true scripts/agents/ai_prompt.sh "$PROMPT" >> "$SUMMARY_FILE" || true
echo "Rapport: $SUMMARY_FILE" echo "Rapport: $SUMMARY_FILE"
popd >/dev/null popd >/dev/null

View File

@ -19,3 +19,4 @@ fi
echo "Version alignment OK" echo "Version alignment OK"

View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail
IMAGE_NAME="4nk-template-dev:debian"
DOCKERFILE="docker/Dockerfile.debian"
echo "[build] ${IMAGE_NAME}"
docker build -t "${IMAGE_NAME}" -f "${DOCKERFILE}" .
echo "[run] launching container and executing agents"
docker run --rm -it \
-v "${PWD}:/work" -w /work \
"${IMAGE_NAME}" \
"scripts/agents/run.sh; ls -la tests/reports/agents || true"

View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail
# Build et lance le conteneur unifié (runner+agents) sur ce projet
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$ROOT_DIR"
# Build image
docker compose -f docker-compose.ci.yml build
# Exécuter agents par défaut
RUNNER_MODE="${RUNNER_MODE:-agents}" BASE_URL="${BASE_URL:-}" REGISTRATION_TOKEN="${REGISTRATION_TOKEN:-}" \
docker compose -f docker-compose.ci.yml up --remove-orphans --abort-on-container-exit

View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"/..
HOOKS_DIR="$REPO_ROOT/.git/hooks"
mkdir -p "$HOOKS_DIR"
install_hook() {
local name="$1" src="$2"
cp -f "$src" "$HOOKS_DIR/$name"
chmod +x "$HOOKS_DIR/$name"
echo "Installed hook: $name"
}
install_hook pre-commit "$REPO_ROOT/scripts/local/precommit.sh"
install_hook pre-push "$REPO_ROOT/scripts/local/prepush.sh"
echo "Hooks installés."

View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
TARGET_BRANCH="${1:-main}"
SOURCE_BRANCH="${2:-}"
if [[ -z "$SOURCE_BRANCH" ]]; then
SOURCE_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
fi
if [[ "$SOURCE_BRANCH" == "$TARGET_BRANCH" ]]; then
echo "Déjà sur $TARGET_BRANCH"; exit 0
fi
# Valider localement avant merge
AUTO_FIX="${AUTO_FIX:-1}" SCOPE="${SCOPE:-all}" scripts/agents/run.sh || true
if [ -f scripts/security/audit.sh ]; then bash scripts/security/audit.sh || true; fi
git fetch origin --prune
git checkout "$TARGET_BRANCH"
git pull --ff-only origin "$TARGET_BRANCH" || true
git merge --no-ff "$SOURCE_BRANCH" -m "[skip ci] merge: $SOURCE_BRANCH -> $TARGET_BRANCH"
git push origin "$TARGET_BRANCH"
echo "Merge effectué: $SOURCE_BRANCH$TARGET_BRANCH"

View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR/.."
# Lint Markdown (best effort)
if command -v npx >/dev/null 2>&1; then
npx -y markdownlint-cli "**/*.md" --ignore "archive/**" || true
fi
# Agents rapides sur fichiers modifiés
AUTO_FIX="${AUTO_FIX:-1}" SCOPE="${SCOPE:-changed}" scripts/agents/run.sh
echo "[pre-commit] OK"

20
scripts/local/prepush.sh Normal file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR/.."
# Agents complets
AUTO_FIX="${AUTO_FIX:-1}" SCOPE="${SCOPE:-all}" scripts/agents/run.sh
# Audit sécurité (best effort)
if [ -f scripts/security/audit.sh ]; then
bash scripts/security/audit.sh || true
fi
# Release guard (dry-run logique)
if [ -f scripts/release/guard.sh ]; then
bash scripts/release/guard.sh || true
fi
echo "[pre-push] OK"

View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
VERSION="${1:-}"
if [[ -z "$VERSION" ]]; then
echo "Usage: $0 vYYYY.MM.P" >&2
exit 2
fi
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR/.."
echo "$VERSION" > TEMPLATE_VERSION
git add TEMPLATE_VERSION CHANGELOG.md 2>/dev/null || true
git commit -m "[skip ci] chore(release): $VERSION" || true
git tag -a "$VERSION" -m "release: $VERSION (latest)"
git push || true
git push origin "$VERSION"
echo "Release locale préparée: $VERSION"

View File

@ -64,3 +64,4 @@ esac
echo "[release-guard] OK" echo "[release-guard] OK"

View File

@ -35,7 +35,7 @@ auto_push() {
# Ajouter tous les changements # Ajouter tous les changements
git add . git add .
# Ne pas commiter si rien à commiter # Ne pas commiter si rien à commite
if [[ -z "$(git diff --cached --name-only)" ]]; then if [[ -z "$(git diff --cached --name-only)" ]]; then
echo " Aucun changement indexé. Skip commit/push." echo " Aucun changement indexé. Skip commit/push."
return 0 return 0

View File

@ -34,3 +34,4 @@ fi
echo "[security-audit] terminé rc=$rc" echo "[security-audit] terminé rc=$rc"
exit $rc exit $rc