diff --git a/docs/workflows/ci_cd_audit_example.md b/docs/workflows/ci_cd_audit_example.md new file mode 100644 index 0000000..25566eb --- /dev/null +++ b/docs/workflows/ci_cd_audit_example.md @@ -0,0 +1,45 @@ +# Audit CI/CD automatique à chaque release majeure + +## Objectif +Planifier et exécuter un audit automatisé de la checklist badge & evidence pack à chaque release majeure. + +## Workflow recommandé +- Utiliser GitHub Actions pour déclencher l’audit lors d’un tag de release majeure (`vX.0.0`). +- Exécuter `tools/auto_check_ci_cd.py` pour valider la checklist. +- Publier le rapport d’audit dans `docs/evidence/` et sur GitHub Pages. + +## Exemple de workflow + +```yaml +name: CI/CD Audit Checklist +on: + push: + tags: + - 'v*.*.*' + workflow_dispatch: + +jobs: + audit-checklist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Installer Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Installer dépendances + run: | + pip install -r requirements-mistral.txt + - name: Exécuter audit checklist + run: | + python3 tools/auto_check_ci_cd.py > docs/evidence/ci_cd_audit_report.txt + - name: Publier rapport sur GitHub Pages + run: | + cp docs/evidence/ci_cd_audit_report.txt public/ +``` + +## Vérification +- Le rapport d’audit est accessible dans `docs/evidence/` et sur GitHub Pages. +- La checklist badge & evidence pack est validée à chaque release majeure. diff --git a/docs/workflows/pages_publish_example.md b/docs/workflows/pages_publish_example.md new file mode 100644 index 0000000..c63809f --- /dev/null +++ b/docs/workflows/pages_publish_example.md @@ -0,0 +1,43 @@ +# Publication automatique des artefacts et endpoints sur GitHub Pages + +## Objectif +Rendre accessibles publiquement les endpoints JSON des badges dynamiques et les artefacts CI/CD via GitHub Pages. + +## Workflow recommandé +- Utiliser GitHub Actions pour publier `docs/badges/*.json`, `endpoints.md`, evidence pack et documentation sur la branche `gh-pages`. +- Déclencher le workflow à chaque push sur `main` ou release majeure. + +## Exemple de workflow + +```yaml +name: Publish Badges & Evidence to GitHub Pages +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + publish-pages: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Préparer les artefacts + run: | + mkdir -p public + cp -r docs/badges/*.json public/ + cp endpoints.md public/ + cp -r docs/evidence public/ + - name: Déployer sur gh-pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./public + force_orphan: true +``` + +## Vérification +- Les endpoints et artefacts sont accessibles sur `https://electron-rare.github.io/Kill_LIFE/`. +- Les badges shields.io peuvent pointer vers les endpoints publiés. diff --git a/workflows/compliance-release.json b/workflows/compliance-release.json new file mode 100644 index 0000000..1f526b8 --- /dev/null +++ b/workflows/compliance-release.json @@ -0,0 +1,118 @@ +{ + "id": "compliance-release", + "title": "Compliance Release", + "category": "release", + "version": 1, + "status": "ready", + "description": "Run compliance and CI audit locally, then dispatch the signed release workflow on GitHub.", + "tags": [ + "compliance", + "release", + "github" + ], + "execution_modes": [ + "local", + "github" + ], + "viewport": { + "width": 1500, + "height": 760 + }, + "nodes": [ + { + "id": "start", + "type": "note", + "label": "Start", + "description": "Prepare release inputs and verify repository posture.", + "x": 80, + "y": 250, + "runner": { + "kind": "none" + }, + "config": {} + }, + { + "id": "compliance", + "type": "local-action", + "label": "Compliance Validate", + "description": "Strict validation of the active compliance profile.", + "x": 280, + "y": 250, + "runner": { + "kind": "local-action", + "action": "compliance.validate" + }, + "config": {} + }, + { + "id": "ci-audit", + "type": "local-action", + "label": "CI Audit", + "description": "Parse and validate the currently tracked workflow files.", + "x": 540, + "y": 250, + "runner": { + "kind": "local-action", + "action": "ci.audit" + }, + "config": {} + }, + { + "id": "manual-review", + "type": "manual-gate", + "label": "Manual Review", + "description": "Operator reviews evidence and confirms readiness before the GitHub dispatch.", + "x": 800, + "y": 250, + "runner": { + "kind": "none" + }, + "config": { + "checklist": [ + "Release notes drafted", + "Evidence reviewed", + "Branch protections green" + ] + } + }, + { + "id": "dispatch-release", + "type": "github-dispatch", + "label": "Dispatch Release Signing", + "description": "Dispatch the GitHub workflow responsible for release signing.", + "x": 1110, + "y": 250, + "runner": { + "kind": "github-dispatch", + "workflow_file": "release_signing.yml", + "ref": "main", + "inputs": { + "source": "mascarade-kill-life-editor" + } + }, + "config": {} + } + ], + "edges": [ + { + "id": "start-compliance", + "source": "start", + "target": "compliance" + }, + { + "id": "compliance-audit", + "source": "compliance", + "target": "ci-audit" + }, + { + "id": "audit-review", + "source": "ci-audit", + "target": "manual-review" + }, + { + "id": "review-dispatch", + "source": "manual-review", + "target": "dispatch-release" + } + ] +} diff --git a/workflows/embedded-ci-local.json b/workflows/embedded-ci-local.json new file mode 100644 index 0000000..a74dd6c --- /dev/null +++ b/workflows/embedded-ci-local.json @@ -0,0 +1,170 @@ +{ + "id": "embedded-ci-local", + "title": "Embedded CI Local", + "category": "embedded", + "version": 1, + "status": "ready", + "description": "Build ESP32, test the native target, and collect evidence packs from the local Kill_LIFE stack.", + "tags": [ + "firmware", + "evidence", + "local" + ], + "execution_modes": [ + "local" + ], + "viewport": { + "width": 1500, + "height": 860 + }, + "nodes": [ + { + "id": "start", + "type": "note", + "label": "Start", + "description": "Entry point for the embedded validation lane.", + "x": 80, + "y": 250, + "runner": { + "kind": "none" + }, + "config": {} + }, + { + "id": "compliance", + "type": "local-action", + "label": "Compliance Validate", + "description": "Run the strict compliance profile before firmware work.", + "x": 300, + "y": 250, + "runner": { + "kind": "local-action", + "action": "compliance.validate" + }, + "config": {} + }, + { + "id": "build-esp", + "type": "local-action", + "label": "Build ESP32", + "description": "Compile the ESP32S3 firmware target.", + "x": 560, + "y": 150, + "runner": { + "kind": "local-action", + "action": "firmware.build.esp" + }, + "config": {} + }, + { + "id": "test-linux", + "type": "local-action", + "label": "Test Native", + "description": "Run the native PlatformIO test suite.", + "x": 560, + "y": 360, + "runner": { + "kind": "local-action", + "action": "firmware.test.linux" + }, + "config": {} + }, + { + "id": "collect-esp", + "type": "local-action", + "label": "Collect ESP Evidence", + "description": "Assemble the evidence pack for the build target.", + "x": 860, + "y": 150, + "runner": { + "kind": "local-action", + "action": "evidence.collect" + }, + "config": { + "target": "esp" + } + }, + { + "id": "verify-esp", + "type": "local-action", + "label": "Verify ESP Evidence", + "description": "Confirm that the ESP evidence pack exists and is valid.", + "x": 1160, + "y": 150, + "runner": { + "kind": "local-action", + "action": "evidence.verify" + }, + "config": { + "target": "esp" + } + }, + { + "id": "collect-linux", + "type": "local-action", + "label": "Collect Native Evidence", + "description": "Assemble the evidence pack for the native test lane.", + "x": 860, + "y": 360, + "runner": { + "kind": "local-action", + "action": "evidence.collect" + }, + "config": { + "target": "linux" + } + }, + { + "id": "verify-linux", + "type": "local-action", + "label": "Verify Native Evidence", + "description": "Confirm that the native evidence pack exists and is valid.", + "x": 1160, + "y": 360, + "runner": { + "kind": "local-action", + "action": "evidence.verify" + }, + "config": { + "target": "linux" + } + } + ], + "edges": [ + { + "id": "start-compliance", + "source": "start", + "target": "compliance" + }, + { + "id": "compliance-build-esp", + "source": "compliance", + "target": "build-esp" + }, + { + "id": "compliance-test-linux", + "source": "compliance", + "target": "test-linux" + }, + { + "id": "build-esp-collect-esp", + "source": "build-esp", + "target": "collect-esp" + }, + { + "id": "collect-esp-verify-esp", + "source": "collect-esp", + "target": "verify-esp" + }, + { + "id": "test-linux-collect-linux", + "source": "test-linux", + "target": "collect-linux" + }, + { + "id": "collect-linux-verify-linux", + "source": "collect-linux", + "target": "verify-linux" + } + ] +} diff --git a/workflows/spec-first.json b/workflows/spec-first.json new file mode 100644 index 0000000..c5b14ea --- /dev/null +++ b/workflows/spec-first.json @@ -0,0 +1,145 @@ +{ + "id": "spec-first", + "title": "Spec First", + "category": "product", + "version": 1, + "status": "draft", + "description": "Drive an issue from intake to specification, plan, tasks, and implementation readiness.", + "tags": [ + "spec", + "planning", + "docs" + ], + "execution_modes": [ + "local" + ], + "viewport": { + "width": 1700, + "height": 860 + }, + "nodes": [ + { + "id": "intake", + "type": "note", + "label": "Issue Intake", + "description": "Capture user intent, severity, and the targeted scope.", + "x": 80, + "y": 300, + "runner": { + "kind": "none" + }, + "config": {} + }, + { + "id": "triage", + "type": "manual-gate", + "label": "Triage", + "description": "Add labels, set risk, and pick the right AI lane.", + "x": 330, + "y": 300, + "runner": { + "kind": "none" + }, + "config": { + "labels": [ + "type:*", + "ai:*", + "risk:*", + "scope:*" + ] + } + }, + { + "id": "spec", + "type": "note", + "label": "Specification", + "description": "Formalize requirements and acceptance criteria.", + "x": 590, + "y": 170, + "runner": { + "kind": "none" + }, + "config": { + "target_doc": "specs/01_spec.md" + } + }, + { + "id": "plan", + "type": "note", + "label": "Plan", + "description": "Pick the technical path and define interfaces.", + "x": 590, + "y": 430, + "runner": { + "kind": "none" + }, + "config": { + "target_doc": "specs/03_plan.md" + } + }, + { + "id": "tasks", + "type": "note", + "label": "Tasks", + "description": "Translate the plan into implementable TODO items.", + "x": 900, + "y": 300, + "runner": { + "kind": "none" + }, + "config": { + "target_doc": "specs/04_tasks.md" + } + }, + { + "id": "impl-ready", + "type": "manual-gate", + "label": "Implementation Ready", + "description": "Final operator checkpoint before opening implementation work.", + "x": 1210, + "y": 300, + "runner": { + "kind": "none" + }, + "config": { + "criteria": [ + "Spec approved", + "Plan approved", + "Tasks actionable" + ] + } + } + ], + "edges": [ + { + "id": "intake-triage", + "source": "intake", + "target": "triage" + }, + { + "id": "triage-spec", + "source": "triage", + "target": "spec" + }, + { + "id": "triage-plan", + "source": "triage", + "target": "plan" + }, + { + "id": "spec-tasks", + "source": "spec", + "target": "tasks" + }, + { + "id": "plan-tasks", + "source": "plan", + "target": "tasks" + }, + { + "id": "tasks-impl-ready", + "source": "tasks", + "target": "impl-ready" + } + ] +} diff --git a/workflows/templates/compliance-release.json b/workflows/templates/compliance-release.json new file mode 100644 index 0000000..a6507dd --- /dev/null +++ b/workflows/templates/compliance-release.json @@ -0,0 +1,118 @@ +{ + "id": "compliance-release", + "title": "Compliance Release", + "category": "release", + "version": 1, + "status": "ready", + "description": "Run compliance and CI audit locally, then dispatch the signed release workflow on GitHub.", + "tags": [ + "compliance", + "release", + "github" + ], + "execution_modes": [ + "local", + "github" + ], + "viewport": { + "width": 1500, + "height": 760 + }, + "nodes": [ + { + "id": "start", + "type": "note", + "label": "Start", + "description": "Prepare release inputs and verify repository posture.", + "x": 80, + "y": 250, + "runner": { + "kind": "none" + }, + "config": {} + }, + { + "id": "compliance", + "type": "local-action", + "label": "Compliance Validate", + "description": "Strict validation of the active compliance profile.", + "x": 280, + "y": 250, + "runner": { + "kind": "local-action", + "action": "compliance.validate" + }, + "config": {} + }, + { + "id": "ci-audit", + "type": "local-action", + "label": "CI Audit", + "description": "Parse and validate the currently tracked workflow files.", + "x": 540, + "y": 250, + "runner": { + "kind": "local-action", + "action": "ci.audit" + }, + "config": {} + }, + { + "id": "manual-review", + "type": "manual-gate", + "label": "Manual Review", + "description": "Operator reviews evidence and confirms readiness before the GitHub dispatch.", + "x": 800, + "y": 250, + "runner": { + "kind": "none" + }, + "config": { + "checklist": [ + "Release notes drafted", + "Evidence reviewed", + "Branch protections green" + ] + } + }, + { + "id": "dispatch-release", + "type": "github-dispatch", + "label": "Dispatch Release Signing", + "description": "Dispatch the GitHub workflow responsible for release signing.", + "x": 1110, + "y": 250, + "runner": { + "kind": "github-dispatch", + "workflow_file": "release_signing.yml", + "ref": "main", + "inputs": { + "source": "crazy-life-kill-life-editor" + } + }, + "config": {} + } + ], + "edges": [ + { + "id": "start-compliance", + "source": "start", + "target": "compliance" + }, + { + "id": "compliance-audit", + "source": "compliance", + "target": "ci-audit" + }, + { + "id": "audit-review", + "source": "ci-audit", + "target": "manual-review" + }, + { + "id": "review-dispatch", + "source": "manual-review", + "target": "dispatch-release" + } + ] +} diff --git a/workflows/templates/embedded-ci-local.json b/workflows/templates/embedded-ci-local.json new file mode 100644 index 0000000..a74dd6c --- /dev/null +++ b/workflows/templates/embedded-ci-local.json @@ -0,0 +1,170 @@ +{ + "id": "embedded-ci-local", + "title": "Embedded CI Local", + "category": "embedded", + "version": 1, + "status": "ready", + "description": "Build ESP32, test the native target, and collect evidence packs from the local Kill_LIFE stack.", + "tags": [ + "firmware", + "evidence", + "local" + ], + "execution_modes": [ + "local" + ], + "viewport": { + "width": 1500, + "height": 860 + }, + "nodes": [ + { + "id": "start", + "type": "note", + "label": "Start", + "description": "Entry point for the embedded validation lane.", + "x": 80, + "y": 250, + "runner": { + "kind": "none" + }, + "config": {} + }, + { + "id": "compliance", + "type": "local-action", + "label": "Compliance Validate", + "description": "Run the strict compliance profile before firmware work.", + "x": 300, + "y": 250, + "runner": { + "kind": "local-action", + "action": "compliance.validate" + }, + "config": {} + }, + { + "id": "build-esp", + "type": "local-action", + "label": "Build ESP32", + "description": "Compile the ESP32S3 firmware target.", + "x": 560, + "y": 150, + "runner": { + "kind": "local-action", + "action": "firmware.build.esp" + }, + "config": {} + }, + { + "id": "test-linux", + "type": "local-action", + "label": "Test Native", + "description": "Run the native PlatformIO test suite.", + "x": 560, + "y": 360, + "runner": { + "kind": "local-action", + "action": "firmware.test.linux" + }, + "config": {} + }, + { + "id": "collect-esp", + "type": "local-action", + "label": "Collect ESP Evidence", + "description": "Assemble the evidence pack for the build target.", + "x": 860, + "y": 150, + "runner": { + "kind": "local-action", + "action": "evidence.collect" + }, + "config": { + "target": "esp" + } + }, + { + "id": "verify-esp", + "type": "local-action", + "label": "Verify ESP Evidence", + "description": "Confirm that the ESP evidence pack exists and is valid.", + "x": 1160, + "y": 150, + "runner": { + "kind": "local-action", + "action": "evidence.verify" + }, + "config": { + "target": "esp" + } + }, + { + "id": "collect-linux", + "type": "local-action", + "label": "Collect Native Evidence", + "description": "Assemble the evidence pack for the native test lane.", + "x": 860, + "y": 360, + "runner": { + "kind": "local-action", + "action": "evidence.collect" + }, + "config": { + "target": "linux" + } + }, + { + "id": "verify-linux", + "type": "local-action", + "label": "Verify Native Evidence", + "description": "Confirm that the native evidence pack exists and is valid.", + "x": 1160, + "y": 360, + "runner": { + "kind": "local-action", + "action": "evidence.verify" + }, + "config": { + "target": "linux" + } + } + ], + "edges": [ + { + "id": "start-compliance", + "source": "start", + "target": "compliance" + }, + { + "id": "compliance-build-esp", + "source": "compliance", + "target": "build-esp" + }, + { + "id": "compliance-test-linux", + "source": "compliance", + "target": "test-linux" + }, + { + "id": "build-esp-collect-esp", + "source": "build-esp", + "target": "collect-esp" + }, + { + "id": "collect-esp-verify-esp", + "source": "collect-esp", + "target": "verify-esp" + }, + { + "id": "test-linux-collect-linux", + "source": "test-linux", + "target": "collect-linux" + }, + { + "id": "collect-linux-verify-linux", + "source": "collect-linux", + "target": "verify-linux" + } + ] +} diff --git a/workflows/templates/spec-first.json b/workflows/templates/spec-first.json new file mode 100644 index 0000000..c5b14ea --- /dev/null +++ b/workflows/templates/spec-first.json @@ -0,0 +1,145 @@ +{ + "id": "spec-first", + "title": "Spec First", + "category": "product", + "version": 1, + "status": "draft", + "description": "Drive an issue from intake to specification, plan, tasks, and implementation readiness.", + "tags": [ + "spec", + "planning", + "docs" + ], + "execution_modes": [ + "local" + ], + "viewport": { + "width": 1700, + "height": 860 + }, + "nodes": [ + { + "id": "intake", + "type": "note", + "label": "Issue Intake", + "description": "Capture user intent, severity, and the targeted scope.", + "x": 80, + "y": 300, + "runner": { + "kind": "none" + }, + "config": {} + }, + { + "id": "triage", + "type": "manual-gate", + "label": "Triage", + "description": "Add labels, set risk, and pick the right AI lane.", + "x": 330, + "y": 300, + "runner": { + "kind": "none" + }, + "config": { + "labels": [ + "type:*", + "ai:*", + "risk:*", + "scope:*" + ] + } + }, + { + "id": "spec", + "type": "note", + "label": "Specification", + "description": "Formalize requirements and acceptance criteria.", + "x": 590, + "y": 170, + "runner": { + "kind": "none" + }, + "config": { + "target_doc": "specs/01_spec.md" + } + }, + { + "id": "plan", + "type": "note", + "label": "Plan", + "description": "Pick the technical path and define interfaces.", + "x": 590, + "y": 430, + "runner": { + "kind": "none" + }, + "config": { + "target_doc": "specs/03_plan.md" + } + }, + { + "id": "tasks", + "type": "note", + "label": "Tasks", + "description": "Translate the plan into implementable TODO items.", + "x": 900, + "y": 300, + "runner": { + "kind": "none" + }, + "config": { + "target_doc": "specs/04_tasks.md" + } + }, + { + "id": "impl-ready", + "type": "manual-gate", + "label": "Implementation Ready", + "description": "Final operator checkpoint before opening implementation work.", + "x": 1210, + "y": 300, + "runner": { + "kind": "none" + }, + "config": { + "criteria": [ + "Spec approved", + "Plan approved", + "Tasks actionable" + ] + } + } + ], + "edges": [ + { + "id": "intake-triage", + "source": "intake", + "target": "triage" + }, + { + "id": "triage-spec", + "source": "triage", + "target": "spec" + }, + { + "id": "triage-plan", + "source": "triage", + "target": "plan" + }, + { + "id": "spec-tasks", + "source": "spec", + "target": "tasks" + }, + { + "id": "plan-tasks", + "source": "plan", + "target": "tasks" + }, + { + "id": "tasks-impl-ready", + "source": "tasks", + "target": "impl-ready" + } + ] +} diff --git a/workflows/workflow.schema.json b/workflows/workflow.schema.json new file mode 100644 index 0000000..6bd027a --- /dev/null +++ b/workflows/workflow.schema.json @@ -0,0 +1,174 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://electron-rare.github.io/Kill_LIFE/workflows/workflow.schema.json", + "title": "Kill_LIFE Workflow", + "type": "object", + "required": [ + "id", + "title", + "category", + "version", + "status", + "execution_modes", + "viewport", + "nodes", + "edges" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$" + }, + "title": { + "type": "string", + "minLength": 3 + }, + "category": { + "type": "string", + "minLength": 2 + }, + "version": { + "type": "integer", + "minimum": 1 + }, + "status": { + "type": "string", + "enum": [ + "draft", + "ready", + "archived" + ] + }, + "description": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "execution_modes": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "local", + "github" + ] + }, + "minItems": 1 + }, + "viewport": { + "type": "object", + "required": [ + "width", + "height" + ], + "properties": { + "width": { + "type": "number", + "minimum": 640 + }, + "height": { + "type": "number", + "minimum": 480 + } + }, + "additionalProperties": false + }, + "nodes": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "type", + "label", + "x", + "y" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$" + }, + "type": { + "type": "string" + }, + "label": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "runner": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "none", + "local-action", + "github-dispatch" + ] + }, + "action": { + "type": "string" + }, + "workflow_file": { + "type": "string" + }, + "ref": { + "type": "string" + }, + "inputs": { + "type": "object" + } + }, + "additionalProperties": true + }, + "config": { + "type": "object" + } + }, + "additionalProperties": true + } + }, + "edges": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "source", + "target" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false +}