retro-portfolio-engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build-and-deploy.yml +105 -0
- package/ADMIN_SETUP.md +306 -0
- package/README.md +300 -0
- package/USAGE.md +451 -0
- package/build.sh +326 -0
- package/index.html +85 -0
- package/js/manifest-loader.js +313 -0
- package/manifest.json +74 -0
- package/package.json +24 -0
- package/setup-admin.sh +134 -0
- package/sync-after-admin.sh +58 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: Build and Deploy Site
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# Manual trigger
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
force_rebuild:
|
|
8
|
+
description: 'Force rebuild (ignore cache)'
|
|
9
|
+
required: false
|
|
10
|
+
type: boolean
|
|
11
|
+
default: false
|
|
12
|
+
|
|
13
|
+
# Scheduled rebuild (daily at midnight UTC)
|
|
14
|
+
schedule:
|
|
15
|
+
- cron: '0 0 * * *'
|
|
16
|
+
|
|
17
|
+
# Trigger on push to main
|
|
18
|
+
push:
|
|
19
|
+
branches:
|
|
20
|
+
- main
|
|
21
|
+
|
|
22
|
+
# Webhook from data repository (requires setup)
|
|
23
|
+
repository_dispatch:
|
|
24
|
+
types: [data-updated]
|
|
25
|
+
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
pages: write
|
|
29
|
+
id-token: write
|
|
30
|
+
|
|
31
|
+
# Prevent concurrent deployments
|
|
32
|
+
concurrency:
|
|
33
|
+
group: "pages"
|
|
34
|
+
cancel-in-progress: false
|
|
35
|
+
|
|
36
|
+
jobs:
|
|
37
|
+
build:
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- name: 📦 Checkout Engine Repository
|
|
42
|
+
uses: actions/checkout@v4
|
|
43
|
+
|
|
44
|
+
- name: 🔧 Install Dependencies
|
|
45
|
+
run: |
|
|
46
|
+
sudo apt-get update
|
|
47
|
+
sudo apt-get install -y jq curl
|
|
48
|
+
|
|
49
|
+
- name: 🏗️ Build Site
|
|
50
|
+
run: |
|
|
51
|
+
# Set execute permission
|
|
52
|
+
chmod +x build.sh
|
|
53
|
+
|
|
54
|
+
# Run build script
|
|
55
|
+
if [ "${{ github.event.inputs.force_rebuild }}" = "true" ]; then
|
|
56
|
+
./build.sh --force
|
|
57
|
+
else
|
|
58
|
+
./build.sh
|
|
59
|
+
fi
|
|
60
|
+
env:
|
|
61
|
+
MANIFEST_URL: ${{ secrets.MANIFEST_URL || 'https://raw.githubusercontent.com/YOUR_USERNAME/retro-portfolio-data/main/manifest.json' }}
|
|
62
|
+
|
|
63
|
+
- name: 📊 Build Summary
|
|
64
|
+
run: |
|
|
65
|
+
echo "### 🎨 Build Summary" >> $GITHUB_STEP_SUMMARY
|
|
66
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
67
|
+
echo "**Build Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> $GITHUB_STEP_SUMMARY
|
|
68
|
+
|
|
69
|
+
if [ -f dist/build-info.json ]; then
|
|
70
|
+
echo "**Manifest Version:** $(jq -r '.version' dist/build-info.json)" >> $GITHUB_STEP_SUMMARY
|
|
71
|
+
echo "**Data Source:** $(jq -r '.dataSource' dist/build-info.json)" >> $GITHUB_STEP_SUMMARY
|
|
72
|
+
echo "**Cache Used:** $(jq -r '.cacheUsed' dist/build-info.json)" >> $GITHUB_STEP_SUMMARY
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
76
|
+
echo "**Files Generated:**" >> $GITHUB_STEP_SUMMARY
|
|
77
|
+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
78
|
+
ls -lh dist/ >> $GITHUB_STEP_SUMMARY
|
|
79
|
+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
80
|
+
|
|
81
|
+
- name: 📤 Upload Artifact
|
|
82
|
+
uses: actions/upload-pages-artifact@v3
|
|
83
|
+
with:
|
|
84
|
+
path: ./dist
|
|
85
|
+
|
|
86
|
+
deploy:
|
|
87
|
+
needs: build
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
|
|
90
|
+
environment:
|
|
91
|
+
name: github-pages
|
|
92
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
93
|
+
|
|
94
|
+
steps:
|
|
95
|
+
- name: 🚀 Deploy to GitHub Pages
|
|
96
|
+
id: deployment
|
|
97
|
+
uses: actions/deploy-pages@v4
|
|
98
|
+
|
|
99
|
+
- name: ✅ Deployment Complete
|
|
100
|
+
run: |
|
|
101
|
+
echo "### 🎉 Deployment Successful!" >> $GITHUB_STEP_SUMMARY
|
|
102
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
103
|
+
echo "**Site URL:** ${{ steps.deployment.outputs.page_url }}" >> $GITHUB_STEP_SUMMARY
|
|
104
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
105
|
+
echo "Your site has been successfully deployed!" >> $GITHUB_STEP_SUMMARY
|
package/ADMIN_SETUP.md
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# 🔧 Configuration de l'Admin pour Site-as-a-Package
|
|
2
|
+
|
|
3
|
+
## 📋 Vue d'ensemble
|
|
4
|
+
|
|
5
|
+
Pour utiliser votre interface admin avec le système Site-as-a-Package, vous avez **deux options** :
|
|
6
|
+
|
|
7
|
+
### **Option A : Admin dans le repo de données** (Recommandé)
|
|
8
|
+
- Admin hébergé dans `retro-portfolio-data`
|
|
9
|
+
- Modifie directement les fichiers data/
|
|
10
|
+
- Commit et push automatique vers GitHub
|
|
11
|
+
- Déclenche rebuild du site engine
|
|
12
|
+
|
|
13
|
+
### **Option B : Admin local séparé**
|
|
14
|
+
- Admin sur votre machine uniquement
|
|
15
|
+
- Utilise l'API Python existante
|
|
16
|
+
- Vous push manuellement vers GitHub
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 🚀 Option A : Admin dans le Data Repo (Recommandé)
|
|
21
|
+
|
|
22
|
+
### Architecture
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
retro-portfolio-data/
|
|
26
|
+
├── config/
|
|
27
|
+
├── data/
|
|
28
|
+
├── lang/
|
|
29
|
+
├── admin/ ← Nouveau dossier
|
|
30
|
+
│ ├── index.html (admin.html)
|
|
31
|
+
│ ├── admin.css
|
|
32
|
+
│ ├── admin.js (logique admin)
|
|
33
|
+
│ └── api/
|
|
34
|
+
│ └── github-sync.php (ou .js pour serverless)
|
|
35
|
+
└── .github/workflows/
|
|
36
|
+
└── notify-engine.yml (notifie le engine après modification)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Fonctionnement
|
|
40
|
+
|
|
41
|
+
1. **Vous modifiez** via l'admin → `retro-portfolio-data.github.io/admin/`
|
|
42
|
+
2. **Admin commit** les changements vers `data/` via GitHub API
|
|
43
|
+
3. **Webhook** notifie `retro-portfolio-engine`
|
|
44
|
+
4. **Engine rebuild** automatiquement avec nouvelles données
|
|
45
|
+
|
|
46
|
+
### Avantages
|
|
47
|
+
|
|
48
|
+
✅ Accessible de partout (web-based)
|
|
49
|
+
✅ Pas besoin de Python local
|
|
50
|
+
✅ Git history automatique
|
|
51
|
+
✅ Rebuild automatique du site
|
|
52
|
+
|
|
53
|
+
### Configuration requise
|
|
54
|
+
|
|
55
|
+
1. **Personal Access Token (PAT)** avec scope `repo`
|
|
56
|
+
2. **GitHub Pages** activé sur `retro-portfolio-data`
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🛠️ Option B : Admin Local (Simple)
|
|
61
|
+
|
|
62
|
+
### Architecture
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
votre-machine/
|
|
66
|
+
├── retro-portfolio-data/ (clone du repo)
|
|
67
|
+
│ ├── config/
|
|
68
|
+
│ ├── data/
|
|
69
|
+
│ └── lang/
|
|
70
|
+
└── admin-local/
|
|
71
|
+
├── admin.html
|
|
72
|
+
├── admin_api.py (votre API existante)
|
|
73
|
+
└── scripts/
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Fonctionnement
|
|
77
|
+
|
|
78
|
+
1. **Clone** `retro-portfolio-data` localement
|
|
79
|
+
2. **Lancez** `python3 admin_api.py`
|
|
80
|
+
3. **Ouvrez** `admin.html` dans le navigateur
|
|
81
|
+
4. **Modifiez** vos données
|
|
82
|
+
5. **Push manuellement** :
|
|
83
|
+
```bash
|
|
84
|
+
cd retro-portfolio-data
|
|
85
|
+
git add data/
|
|
86
|
+
git commit -m "Update content via admin"
|
|
87
|
+
git push
|
|
88
|
+
```
|
|
89
|
+
6. **Rebuild** déclenché automatiquement
|
|
90
|
+
|
|
91
|
+
### Avantages
|
|
92
|
+
|
|
93
|
+
✅ Utilise votre admin existant
|
|
94
|
+
✅ Pas de configuration complexe
|
|
95
|
+
✅ Contrôle total
|
|
96
|
+
|
|
97
|
+
### Inconvénients
|
|
98
|
+
|
|
99
|
+
❌ Nécessite Python local
|
|
100
|
+
❌ Push manuel requis
|
|
101
|
+
❌ Pas accessible à distance
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 🎨 Configuration de l'Option B (Quick Start)
|
|
106
|
+
|
|
107
|
+
### 1. Préparer le repo de données
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Créer et cloner le repo de données
|
|
111
|
+
git clone https://github.com/YOUR_USERNAME/retro-portfolio-data.git
|
|
112
|
+
cd retro-portfolio-data
|
|
113
|
+
|
|
114
|
+
# Copier vos données existantes
|
|
115
|
+
cp -r ../retro-portfolio/config ./
|
|
116
|
+
cp -r ../retro-portfolio/data ./
|
|
117
|
+
cp -r ../retro-portfolio/lang ./
|
|
118
|
+
|
|
119
|
+
git add .
|
|
120
|
+
git commit -m "Initial data import"
|
|
121
|
+
git push
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 2. Configurer l'admin local
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Créer dossier admin
|
|
128
|
+
mkdir -p admin-local
|
|
129
|
+
|
|
130
|
+
# Copier admin files
|
|
131
|
+
cp ../retro-portfolio/admin.html admin-local/
|
|
132
|
+
cp ../retro-portfolio/admin.css admin-local/
|
|
133
|
+
cp ../retro-portfolio/admin_api.py admin-local/
|
|
134
|
+
cp -r ../retro-portfolio/scripts admin-local/
|
|
135
|
+
|
|
136
|
+
# Copier .env (credentials Cloudinary)
|
|
137
|
+
cp ../retro-portfolio/.env admin-local/
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 3. Modifier admin_api.py pour pointer vers le data repo
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
# admin-local/admin_api.py
|
|
144
|
+
|
|
145
|
+
# Modifier les chemins
|
|
146
|
+
DATA_DIR = '../retro-portfolio-data/data'
|
|
147
|
+
CONFIG_DIR = '../retro-portfolio-data/config'
|
|
148
|
+
LANG_DIR = '../retro-portfolio-data/lang'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 4. Lancer l'admin
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cd admin-local
|
|
155
|
+
python3 admin_api.py
|
|
156
|
+
|
|
157
|
+
# Dans un autre terminal
|
|
158
|
+
cd retro-portfolio-data
|
|
159
|
+
python3 -m http.server 8001
|
|
160
|
+
|
|
161
|
+
# Ouvrir http://localhost:8001/admin-local/admin.html
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 5. Workflow de mise à jour
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Après modification via admin
|
|
168
|
+
cd retro-portfolio-data
|
|
169
|
+
|
|
170
|
+
# Vérifier les changements
|
|
171
|
+
git status
|
|
172
|
+
|
|
173
|
+
# Commit
|
|
174
|
+
git add data/ lang/
|
|
175
|
+
git commit -m "Update content via admin"
|
|
176
|
+
|
|
177
|
+
# Push (déclenche rebuild automatique)
|
|
178
|
+
git push
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 🌐 Configuration de l'Option A (Avancé)
|
|
184
|
+
|
|
185
|
+
### 1. Activer GitHub Pages sur le data repo
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Dans retro-portfolio-data/
|
|
189
|
+
mkdir -p admin
|
|
190
|
+
cp ../retro-portfolio/admin.html admin/index.html
|
|
191
|
+
cp ../retro-portfolio/admin.css admin/
|
|
192
|
+
|
|
193
|
+
git add admin/
|
|
194
|
+
git commit -m "Add web-based admin"
|
|
195
|
+
git push
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Settings → Pages → Source: `main` branch → `/` (root)
|
|
199
|
+
|
|
200
|
+
### 2. Créer l'API serverless
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// admin/api/sync.js (pour Vercel/Netlify)
|
|
204
|
+
import { Octokit } from "@octokit/rest";
|
|
205
|
+
|
|
206
|
+
export default async function handler(req, res) {
|
|
207
|
+
if (req.method !== 'POST') {
|
|
208
|
+
return res.status(405).json({ error: 'Method not allowed' });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const { category, data, message } = req.body;
|
|
212
|
+
const PAT = process.env.GITHUB_PAT;
|
|
213
|
+
|
|
214
|
+
const octokit = new Octokit({ auth: PAT });
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
// Get current file content
|
|
218
|
+
const { data: currentFile } = await octokit.repos.getContent({
|
|
219
|
+
owner: 'YOUR_USERNAME',
|
|
220
|
+
repo: 'retro-portfolio-data',
|
|
221
|
+
path: `data/${category}.json`,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Update file
|
|
225
|
+
await octokit.repos.createOrUpdateFileContents({
|
|
226
|
+
owner: 'YOUR_USERNAME',
|
|
227
|
+
repo: 'retro-portfolio-data',
|
|
228
|
+
path: `data/${category}.json`,
|
|
229
|
+
message: message || 'Update via admin',
|
|
230
|
+
content: Buffer.from(JSON.stringify(data, null, 2)).toString('base64'),
|
|
231
|
+
sha: currentFile.sha,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
res.status(200).json({ success: true });
|
|
235
|
+
} catch (error) {
|
|
236
|
+
res.status(500).json({ error: error.message });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 3. Adapter admin.html
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
// Dans admin.html, remplacer les appels API
|
|
245
|
+
|
|
246
|
+
async function saveData(category, items) {
|
|
247
|
+
const response = await fetch('/api/sync', {
|
|
248
|
+
method: 'POST',
|
|
249
|
+
headers: { 'Content-Type': 'application/json' },
|
|
250
|
+
body: JSON.stringify({
|
|
251
|
+
category,
|
|
252
|
+
data: { items },
|
|
253
|
+
message: `Update ${category} via web admin`
|
|
254
|
+
})
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
if (!response.ok) throw new Error('Failed to save');
|
|
258
|
+
|
|
259
|
+
// Déclencher rebuild du engine
|
|
260
|
+
await triggerRebuild();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async function triggerRebuild() {
|
|
264
|
+
await fetch('https://api.github.com/repos/YOUR_USERNAME/retro-portfolio-engine/dispatches', {
|
|
265
|
+
method: 'POST',
|
|
266
|
+
headers: {
|
|
267
|
+
'Authorization': `token ${GITHUB_PAT}`,
|
|
268
|
+
'Accept': 'application/vnd.github+json'
|
|
269
|
+
},
|
|
270
|
+
body: JSON.stringify({ event_type: 'data-updated' })
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 🔐 Sécurité
|
|
278
|
+
|
|
279
|
+
### Pour l'Option A (Web Admin)
|
|
280
|
+
|
|
281
|
+
1. **Protéger l'admin** avec authentification
|
|
282
|
+
2. **Utiliser des secrets** pour le PAT (variables d'environnement)
|
|
283
|
+
3. **Limiter les permissions** du PAT au strict nécessaire
|
|
284
|
+
|
|
285
|
+
### Pour l'Option B (Local Admin)
|
|
286
|
+
|
|
287
|
+
1. **Ne jamais commit** votre `.env` avec credentials
|
|
288
|
+
2. **Ajouter** `.env` au `.gitignore`
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 📊 Recommandation
|
|
293
|
+
|
|
294
|
+
Pour votre cas, je recommande **Option B** car :
|
|
295
|
+
|
|
296
|
+
✅ Plus simple à mettre en place
|
|
297
|
+
✅ Réutilise votre admin existant
|
|
298
|
+
✅ Pas de configuration serverless
|
|
299
|
+
✅ Contrôle total local
|
|
300
|
+
|
|
301
|
+
Le workflow devient :
|
|
302
|
+
```
|
|
303
|
+
Modifier via admin local → git push → Rebuild auto du site
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Voulez-vous que je vous prépare les scripts pour l'Option B ?
|
package/README.md
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# 🎨 Site-as-a-Package Engine
|
|
2
|
+
|
|
3
|
+
Un moteur de site web autonome qui récupère son contenu depuis un repo distant et se construit automatiquement. Concept **Site-as-a-Package** : le code du moteur est séparé des données.
|
|
4
|
+
|
|
5
|
+
## 🚀 Concept
|
|
6
|
+
|
|
7
|
+
Au lieu d'avoir un site avec du contenu figé, ce repo contient uniquement :
|
|
8
|
+
|
|
9
|
+
1. **Le moteur de rendu** (HTML, CSS, JS)
|
|
10
|
+
2. **Un script de build** qui récupère les données distantes
|
|
11
|
+
3. **Une GitHub Action** qui automatise tout
|
|
12
|
+
|
|
13
|
+
Les **données, traductions et configurations** sont stockées dans un repo séparé. À chaque build, le moteur récupère la dernière version du contenu.
|
|
14
|
+
|
|
15
|
+
## 📁 Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
retro-portfolio-engine/ (Ce repo - Le moteur)
|
|
19
|
+
├── index.html Squelette HTML
|
|
20
|
+
├── style.css, fonts.css Styles
|
|
21
|
+
├── js/
|
|
22
|
+
│ ├── manifest-loader.js Charge le manifest distribué
|
|
23
|
+
│ ├── i18n.js, render.js Modules du moteur
|
|
24
|
+
│ └── ...
|
|
25
|
+
├── build.sh Script de build avec cache
|
|
26
|
+
├── manifest.json Configuration du data repo
|
|
27
|
+
└── .github/workflows/
|
|
28
|
+
└── build-and-deploy.yml Automatisation GitHub
|
|
29
|
+
|
|
30
|
+
retro-portfolio-data/ (Repo séparé - Les données)
|
|
31
|
+
├── manifest.json Point d'entrée
|
|
32
|
+
├── config/
|
|
33
|
+
│ ├── app.json
|
|
34
|
+
│ ├── languages.json
|
|
35
|
+
│ └── categories.json
|
|
36
|
+
├── data/
|
|
37
|
+
│ ├── painting.json
|
|
38
|
+
│ └── ...
|
|
39
|
+
└── lang/
|
|
40
|
+
├── en.json
|
|
41
|
+
└── fr.json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 🔧 Installation
|
|
45
|
+
|
|
46
|
+
### 1. Cloner le repo moteur
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone https://github.com/YOUR_USERNAME/retro-portfolio-engine.git
|
|
50
|
+
cd retro-portfolio-engine
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2. Configurer le manifest
|
|
54
|
+
|
|
55
|
+
Éditez `manifest.json` et changez les URLs :
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"dataRepository": {
|
|
60
|
+
"owner": "YOUR_USERNAME",
|
|
61
|
+
"repo": "retro-portfolio-data",
|
|
62
|
+
"branch": "main",
|
|
63
|
+
"baseUrl": "https://raw.githubusercontent.com/YOUR_USERNAME/retro-portfolio-data/main/"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Build local (avec cache)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Build normal (utilise le cache si disponible)
|
|
72
|
+
./build.sh
|
|
73
|
+
|
|
74
|
+
# Force le re-téléchargement complet
|
|
75
|
+
./build.sh --force
|
|
76
|
+
|
|
77
|
+
# Tester localement
|
|
78
|
+
cd dist
|
|
79
|
+
python3 -m http.server 8000
|
|
80
|
+
# Ouvrir http://localhost:8000
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. Déploiement automatique sur GitHub Pages
|
|
84
|
+
|
|
85
|
+
1. **Activer GitHub Pages** dans les paramètres du repo :
|
|
86
|
+
- Settings → Pages
|
|
87
|
+
- Source : **GitHub Actions**
|
|
88
|
+
|
|
89
|
+
2. **Configurer le secret (optionnel)** :
|
|
90
|
+
- Settings → Secrets → Actions
|
|
91
|
+
- Ajouter `MANIFEST_URL` si votre manifest est ailleurs
|
|
92
|
+
|
|
93
|
+
3. **Déclencher un build** :
|
|
94
|
+
- Push sur `main` → build automatique
|
|
95
|
+
- Actions → Build and Deploy Site → Run workflow
|
|
96
|
+
|
|
97
|
+
## 🎯 Utilisation
|
|
98
|
+
|
|
99
|
+
### Mode 1 : Build automatique (recommandé)
|
|
100
|
+
|
|
101
|
+
GitHub Action se déclenche automatiquement :
|
|
102
|
+
|
|
103
|
+
- ✅ À chaque push sur `main`
|
|
104
|
+
- ✅ Tous les jours à minuit (récupère les nouvelles données)
|
|
105
|
+
- ✅ Manuellement depuis l'onglet Actions
|
|
106
|
+
|
|
107
|
+
### Mode 2 : Build manuel
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Build avec cache (rapide)
|
|
111
|
+
./build.sh
|
|
112
|
+
|
|
113
|
+
# Build complet (ignore le cache)
|
|
114
|
+
./build.sh --force
|
|
115
|
+
|
|
116
|
+
# Build avec manifest custom
|
|
117
|
+
./build.sh --manifest https://example.com/manifest.json
|
|
118
|
+
|
|
119
|
+
# Options avancées
|
|
120
|
+
./build.sh --help
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 🔄 Mettre à jour le contenu
|
|
124
|
+
|
|
125
|
+
### Option A : Modifier le repo de données
|
|
126
|
+
|
|
127
|
+
1. Modifier les fichiers dans `retro-portfolio-data/`
|
|
128
|
+
2. Commit & push
|
|
129
|
+
3. (Optionnel) Déclencher un rebuild du moteur
|
|
130
|
+
|
|
131
|
+
### Option B : Utiliser un webhook
|
|
132
|
+
|
|
133
|
+
Configurez le repo de données pour notifier le moteur :
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
# Dans retro-portfolio-data/.github/workflows/notify.yml
|
|
137
|
+
on:
|
|
138
|
+
push:
|
|
139
|
+
branches: [main]
|
|
140
|
+
|
|
141
|
+
jobs:
|
|
142
|
+
notify-engine:
|
|
143
|
+
runs-on: ubuntu-latest
|
|
144
|
+
steps:
|
|
145
|
+
- name: Trigger rebuild
|
|
146
|
+
run: |
|
|
147
|
+
curl -X POST \
|
|
148
|
+
-H "Authorization: token ${{ secrets.PAT_TOKEN }}" \
|
|
149
|
+
https://api.github.com/repos/YOUR_USERNAME/retro-portfolio-engine/dispatches \
|
|
150
|
+
-d '{"event_type": "data-updated"}'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## 🛡️ Sécurité et Bonnes Pratiques
|
|
154
|
+
|
|
155
|
+
### ✅ CORS
|
|
156
|
+
|
|
157
|
+
`raw.githubusercontent.com` envoie automatiquement `Access-Control-Allow-Origin: *`, donc **pas de problème CORS** pour les requêtes GET.
|
|
158
|
+
|
|
159
|
+
### ✅ Validation des données
|
|
160
|
+
|
|
161
|
+
Le `manifest-loader.js` valide la structure du manifest :
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
validateManifest(manifest) {
|
|
165
|
+
const required = ['version', 'dataRepository', 'structure'];
|
|
166
|
+
// Validation stricte
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### ✅ Cache intelligent
|
|
171
|
+
|
|
172
|
+
Le script `build.sh` utilise un cache local (`.cache/`) :
|
|
173
|
+
|
|
174
|
+
- ⚡ Accélère les builds répétés
|
|
175
|
+
- 🔄 TTL de 1 heure par défaut
|
|
176
|
+
- 🔨 Option `--force` pour forcer le refresh
|
|
177
|
+
|
|
178
|
+
### ✅ Sanitisation
|
|
179
|
+
|
|
180
|
+
Tous les contenus HTML sont sanitisés pour éviter les XSS :
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
sanitizeHTML(str) {
|
|
184
|
+
const temp = document.createElement('div');
|
|
185
|
+
temp.textContent = str;
|
|
186
|
+
return temp.innerHTML;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 📊 Fonctionnalités
|
|
191
|
+
|
|
192
|
+
### ✨ Avantages
|
|
193
|
+
|
|
194
|
+
- **🔄 Toujours à jour** : Récupère la dernière version du contenu à chaque build
|
|
195
|
+
- **📦 Léger** : Le repo moteur est quasi vide
|
|
196
|
+
- **🌍 Multi-langues** : Support natif de plusieurs langues
|
|
197
|
+
- **⚡ Performant** : Cache intelligent, build optimisé
|
|
198
|
+
- **🔒 Sécurisé** : Validation, sanitisation, pas d'eval()
|
|
199
|
+
- **🚀 Zero-config** : Push et c'est déployé
|
|
200
|
+
|
|
201
|
+
### 🎨 Personnalisation
|
|
202
|
+
|
|
203
|
+
Vous pouvez modifier :
|
|
204
|
+
|
|
205
|
+
- `style.css` : Apparence visuelle
|
|
206
|
+
- `js/render.js` : Logique de rendu
|
|
207
|
+
- `manifest.json` : Source des données
|
|
208
|
+
|
|
209
|
+
## 🐛 Dépannage
|
|
210
|
+
|
|
211
|
+
### Le build échoue
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Vérifier que jq est installé
|
|
215
|
+
which jq
|
|
216
|
+
|
|
217
|
+
# Tester manuellement le manifest
|
|
218
|
+
curl https://raw.githubusercontent.com/YOUR_USERNAME/retro-portfolio-data/main/manifest.json
|
|
219
|
+
|
|
220
|
+
# Build en mode verbose
|
|
221
|
+
bash -x build.sh
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Les données ne se mettent pas à jour
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Forcer le re-téléchargement
|
|
228
|
+
./build.sh --force
|
|
229
|
+
|
|
230
|
+
# Vider le cache
|
|
231
|
+
rm -rf .cache
|
|
232
|
+
./build.sh
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### GitHub Action échoue
|
|
236
|
+
|
|
237
|
+
1. Vérifier que GitHub Pages est activé
|
|
238
|
+
2. Vérifier les permissions dans Settings → Actions → Workflow permissions
|
|
239
|
+
3. Consulter les logs dans Actions → Build and Deploy
|
|
240
|
+
|
|
241
|
+
## 📚 Documentation Avancée
|
|
242
|
+
|
|
243
|
+
### Structure du Manifest
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"version": "1.0.0",
|
|
248
|
+
"dataRepository": {
|
|
249
|
+
"type": "github",
|
|
250
|
+
"baseUrl": "https://raw.githubusercontent.com/..."
|
|
251
|
+
},
|
|
252
|
+
"structure": {
|
|
253
|
+
"config": {
|
|
254
|
+
"app": "config/app.json",
|
|
255
|
+
"languages": "config/languages.json"
|
|
256
|
+
},
|
|
257
|
+
"data": {
|
|
258
|
+
"painting": "data/painting.json"
|
|
259
|
+
},
|
|
260
|
+
"lang": {
|
|
261
|
+
"en": "lang/en.json"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### API du ManifestLoader
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
// Initialiser
|
|
271
|
+
await ManifestLoader.init('./manifest.json');
|
|
272
|
+
|
|
273
|
+
// Récupérer des URLs
|
|
274
|
+
const appConfigUrl = ManifestLoader.getConfigUrl('app');
|
|
275
|
+
const paintingUrl = ManifestLoader.getDataUrl('painting');
|
|
276
|
+
const frTransUrl = ManifestLoader.getLangUrl('fr');
|
|
277
|
+
|
|
278
|
+
// Lister les langues disponibles
|
|
279
|
+
const langs = ManifestLoader.getAvailableLanguages();
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 🤝 Contribution
|
|
283
|
+
|
|
284
|
+
Les contributions sont les bienvenues ! Pour contribuer :
|
|
285
|
+
|
|
286
|
+
1. Fork le projet
|
|
287
|
+
2. Créer une branche (`git checkout -b feature/amazing`)
|
|
288
|
+
3. Commit vos changements
|
|
289
|
+
4. Push et créer une Pull Request
|
|
290
|
+
|
|
291
|
+
## 📄 Licence
|
|
292
|
+
|
|
293
|
+
MIT License - Utilisation libre
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
**Fait avec 💜 par Alex**
|
|
298
|
+
|
|
299
|
+
🔗 [Demo](https://YOUR_USERNAME.github.io/retro-portfolio-engine/)
|
|
300
|
+
🐛 [Issues](https://github.com/YOUR_USERNAME/retro-portfolio-engine/issues)
|