Compare commits
6 Commits
38284dabb6
...
b43cf6f036
| Author | SHA1 | Date | |
|---|---|---|---|
| b43cf6f036 | |||
| b573d20aab | |||
| 063f3ecc75 | |||
| 3db249f3e1 | |||
| fcc04895f3 | |||
| d037af11b6 |
@@ -1,5 +1,93 @@
|
|||||||
name: Déploiement AEGIS Portal
|
name: Déploiement AEGIS Portal
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
- test
|
||||||
|
- acc
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GIT_SSL_NO_VERIFY: "true"
|
||||||
|
NODE_TLS_REJECT_UNAUTHORIZED: "0"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Patch DNS local pour Gitea Runner
|
||||||
|
run: sudo echo "10.10.40.31 git.bunker.lan" | sudo tee -a /etc/hosts
|
||||||
|
|
||||||
|
- name: Configuration de Git pour SSL
|
||||||
|
run: git config --global http.sslVerify false
|
||||||
|
|
||||||
|
- name: Récupération du code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configuration de Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
|
- name: Activation de pnpm
|
||||||
|
run: corepack enable pnpm
|
||||||
|
|
||||||
|
- name: Installation des dépendances
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Compilation de la Build
|
||||||
|
env:
|
||||||
|
VITE_APP_ENV: ${{ github.ref_name }}
|
||||||
|
VITE_PB_URL: ${{ secrets.PB_URL }}
|
||||||
|
run: pnpm run build
|
||||||
|
|
||||||
|
- name: Installation de lftp
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y lftp
|
||||||
|
|
||||||
|
- name: Routage et Déploiement FTP
|
||||||
|
env: # 1. On charge tous les secrets de manière sécurisée
|
||||||
|
SERVER: ${{ secrets.FTP_SERVER }}
|
||||||
|
DEV_U: ${{ secrets.DEV_FTP_USER }}
|
||||||
|
DEV_P: ${{ secrets.DEV_FTP_PASSWORD }}
|
||||||
|
TEST_U: ${{ secrets.TEST_FTP_USER }}
|
||||||
|
TEST_P: ${{ secrets.TEST_FTP_PASSWORD }}
|
||||||
|
ACC_U: ${{ secrets.ACC_FTP_USER }}
|
||||||
|
ACC_P: ${{ secrets.ACC_FTP_PASSWORD }}
|
||||||
|
PROD_U: ${{ secrets.PROD_FTP_USER }}
|
||||||
|
PROD_P: ${{ secrets.PROD_FTP_PASSWORD }}
|
||||||
|
BRANCH: ${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
# 2. On attribue les bons identifiants selon la branche
|
||||||
|
if [ "$BRANCH" == "master" ]; then
|
||||||
|
TARGET_USER=$PROD_U; TARGET_PASS=$PROD_P;
|
||||||
|
elif [ "$BRANCH" == "acc" ]; then
|
||||||
|
TARGET_USER=$ACC_U; TARGET_PASS=$ACC_P;
|
||||||
|
elif [ "$BRANCH" == "test" ]; then
|
||||||
|
TARGET_USER=$TEST_U; TARGET_PASS=$TEST_P;
|
||||||
|
else
|
||||||
|
TARGET_USER=$DEV_U; TARGET_PASS=$DEV_P;
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Déploiement de la branche [$BRANCH]"
|
||||||
|
|
||||||
|
# 3. Exécution du script FTP
|
||||||
|
cat << EOF > script.lftp
|
||||||
|
set ftp:passive-mode true
|
||||||
|
set ftp:ssl-allow no
|
||||||
|
set ssl:verify-certificate no
|
||||||
|
set net:timeout 5
|
||||||
|
set net:max-retries 2
|
||||||
|
set dns:fatal-timeout 2
|
||||||
|
open -u "${TARGET_USER}","${TARGET_PASS}" "${SERVER}"
|
||||||
|
cd home/${TARGET_USER}
|
||||||
|
mirror -R --delete --verbose dist/ ./
|
||||||
|
quit
|
||||||
|
EOF
|
||||||
|
|
||||||
|
lftp -f script.lftp
|
||||||
|
name: Déploiement AEGIS Portal
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
|||||||
@@ -1,5 +1,45 @@
|
|||||||
name: Sécurité - Architecture Git-Flow
|
name: Sécurité - Architecture Git-Flow
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
- test
|
||||||
|
- acc
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-flow:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Vérification du flux de promotion
|
||||||
|
run: |
|
||||||
|
TARGET_BRANCH="${{ github.base_ref }}"
|
||||||
|
SOURCE_BRANCH="${{ github.head_ref }}"
|
||||||
|
|
||||||
|
echo "Tentative de promotion : $SOURCE_BRANCH ➔ $TARGET_BRANCH"
|
||||||
|
|
||||||
|
# Règle 1 : Vers TEST (Doit venir de DEV)
|
||||||
|
if [ "$TARGET_BRANCH" == "test" ] && [ "$SOURCE_BRANCH" != "dev" ]; then
|
||||||
|
echo "ERREUR : L'environnement TEST ne peut recevoir que du code de DEV."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Règle 2 : Vers ACC (Doit venir de TEST)
|
||||||
|
if [ "$TARGET_BRANCH" == "acc" ] && [ "$SOURCE_BRANCH" != "test" ]; then
|
||||||
|
echo "ERREUR : L'environnement d'ACCEPTATION ne peut recevoir que du code de TEST."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Règle 3 : Vers PROD (Doit venir de ACC)
|
||||||
|
if [ "$TARGET_BRANCH" == "master" ] && [ "$SOURCE_BRANCH" != "acc" ]; then
|
||||||
|
echo "ERREUR : La PRODUCTION ne peut recevoir que du code validé en ACCEPTATION (acc)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Flux réglementaire respecté ! Promotion autorisée."
|
||||||
|
name: Sécurité - Architecture Git-Flow
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
|
|||||||
@@ -1,5 +1,64 @@
|
|||||||
name: Contrôle Qualité & Sécurité (QA)
|
name: Contrôle Qualité & Sécurité (QA)
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
- test
|
||||||
|
- acc
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
quality-gate:
|
||||||
|
name: qa-s-check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
GIT_SSL_NO_VERIFY: "true"
|
||||||
|
NODE_TLS_REJECT_UNAUTHORIZED: "0"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Patch DNS local pour Gitea Runner
|
||||||
|
run: sudo echo "10.10.40.31 git.bunker.lan" | sudo tee -a /etc/hosts
|
||||||
|
|
||||||
|
- name: Configuration de Git pour SSL
|
||||||
|
run: git config --global http.sslVerify false
|
||||||
|
|
||||||
|
- name: Récupération du code source
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configuration de Node.js (v22)
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
|
- name: Activation de pnpm
|
||||||
|
run: corepack enable pnpm
|
||||||
|
|
||||||
|
- name: Installation des dépendances
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Étape 1 : ESLint (Syntaxe et conventions)
|
||||||
|
- name: Analyse Linter (ESLint)
|
||||||
|
run: pnpm run lint
|
||||||
|
|
||||||
|
# Étape 2 : Verification stricte des types TypeScript (sans émettre de fichiers)
|
||||||
|
- name: Verification des Types TypeScript
|
||||||
|
run: pnpm exec tsc --noEmit
|
||||||
|
|
||||||
|
# Étape 3 : Exécution des tests unitaires
|
||||||
|
- name: Tests Unitaires (Vitest)
|
||||||
|
run: pnpm run test -- --run
|
||||||
|
|
||||||
|
# Étape 4 : Audit des vulnérabilités npm (Niveau High/Critical)
|
||||||
|
- name: Audit de Sécurité des Dépendances
|
||||||
|
run: pnpm audit --audit-level=high
|
||||||
|
|
||||||
|
# Étape 5 : Validation de la compilation ViteJS
|
||||||
|
- name: Validation du Build de Production
|
||||||
|
run: pnpm run build
|
||||||
|
name: Contrôle Qualité & Sécurité (QA)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
|
|||||||
@@ -22,3 +22,4 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
// Séparation discrète (bordure fine plutôt qu'ombre inset, pour rester léger)
|
// Séparation discrète (bordure fine plutôt qu'ombre inset, pour rester léger)
|
||||||
"px-6 py-5 flex flex-col space-y-1.5 border-b border-black/5 dark:border-white/5 transition-all duration-300 ease-in-out",
|
"px-6 py-5 flex flex-col space-y-1.5 border-black/5 dark:border-white/5 transition-all duration-300",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|||||||
"bg-[#e8e8e8] dark:bg-[#1e293b]",
|
"bg-[#e8e8e8] dark:bg-[#1e293b]",
|
||||||
"text-slate-800 dark:text-slate-100 font-medium placeholder:text-slate-400 dark:placeholder:text-slate-500",
|
"text-slate-800 dark:text-slate-100 font-medium placeholder:text-slate-400 dark:placeholder:text-slate-500",
|
||||||
|
|
||||||
// 🎯 Utilisation directe de tes constantes Neumorphic creusées
|
// Utilisation directe de tes constantes Neumorphic creusées
|
||||||
NEUMORPHISM.insetLight,
|
NEUMORPHISM.insetLight,
|
||||||
NEUMORPHISM.insetDark,
|
NEUMORPHISM.insetDark,
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ export default function BackupWidget({ onClick }: BackupWidgetProps) {
|
|||||||
<Badge className="max-w-fit min-w-fit" name="PRA Immuable">
|
<Badge className="max-w-fit min-w-fit" name="PRA Immuable">
|
||||||
</Badge>
|
</Badge>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="p-6">
|
<CardContent className="p-6 flex flex-col h-full">
|
||||||
<Card variant='digged' className="bg-slate-50 rounded-lg p-4 border border-slate-100 mb-4">
|
<Card variant="flat" className="rounded-lg p-4 border border-slate-100 mb-4">
|
||||||
<p className="text-sm text-slate-500 mb-1">Dernier snapshot système</p>
|
<p className="text-sm text-slate-500 mb-1">Dernier snapshot système</p>
|
||||||
<p className="text-slate-900 font-medium">Aujourd'hui à 03:00 AM</p>
|
<p className="text-slate-900 font-medium">Aujourd'hui à 03:00 AM</p>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ export default function ServicesWidget() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="lg" onClick={() => navigate('/evolution-infrastructure')}>
|
<Button className ="text-green-600" size="lg" onClick={() => navigate('/evolution-infrastructure')}>
|
||||||
Demander une évolution du parc
|
Mise à niveau du Parc
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ export const SupportCtaWidget: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="p-6">
|
<CardContent className="p-6 rounded-xl">
|
||||||
<h3 className="text-lg font-semibold mb-2">Centre de Support</h3>
|
<h3 className="text-lg font-semibold mb-2">Centre de Support</h3>
|
||||||
<p className="text-blue-900 text-sm mb-4 leading-relaxed">
|
<p className="text-sm mb-4 leading-relaxed">
|
||||||
Déclarez un incident critique ou demandez une évolution de votre infrastructure.
|
Déclarez un incident critique ou demandez une évolution de votre infrastructure.
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => navigate('/support')}
|
onClick={() => navigate('/support')}
|
||||||
className="w-full text-blue-900"
|
className= "text-rose-500 w-full"
|
||||||
>
|
>
|
||||||
Ouvrir un ticket sécurisé
|
Ouvrir un ticket sécurisé
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const SupportFooterWidget: React.FC<SupportFooterWidgetProps> = ({
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-12 bg-slate-900 text-slate-300 rounded-xl p-6 flex flex-col sm:flex-row items-center justify-between gap-4 shadow-sm">
|
<div className="mt-12 bg-slate-500 text-slate-300 rounded-xl p-6 flex flex-col sm:flex-row items-center justify-between gap-4 shadow-sm">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-sm font-bold text-white">{title}</h4>
|
<h4 className="text-sm font-bold text-white">{title}</h4>
|
||||||
<p className="text-xs text-slate-400 mt-0.5">
|
<p className="text-xs text-slate-400 mt-0.5">
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default function ServiceDesk() {
|
|||||||
title="Centre de Support (Service Desk)"
|
title="Centre de Support (Service Desk)"
|
||||||
description="Canal de communication sécurisé avec vos experts GISE."
|
description="Canal de communication sécurisé avec vos experts GISE."
|
||||||
>
|
>
|
||||||
<Button onClick={() => navigate('/support/new')}>
|
<Button className= "text-rose-500" onClick={() => navigate('/support/new')}>
|
||||||
Ouvrir un ticket sécurisé
|
Ouvrir un ticket sécurisé
|
||||||
</Button>
|
</Button>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
|
|||||||
Reference in New Issue
Block a user