@@ -69,150 +69,7 @@ jobs:
6969 - name : Prepare static site folder (scan apps & generate index)
7070 run : |
7171 set -e
72-
73- SITE_DIR="site"
74- mkdir -p "$SITE_DIR"
75-
76- python << 'PYTHON_EOF'
77- import json, os, shutil, html
78-
79- ROOT = os.getcwd()
80- SITE_DIR = os.path.join(ROOT, "site")
81- os.makedirs(SITE_DIR, exist_ok=True)
82-
83- release_tag = os.environ.get("GITHUB_REF_NAME", "")
84-
85- apps = []
86-
87- # Walk repo and look for webapp.json
88- for dirpath, dirnames, filenames in os.walk(ROOT):
89- if "webapp.json" not in filenames:
90- continue
91-
92- meta_path = os.path.join(dirpath, "webapp.json")
93- with open(meta_path, "r", encoding="utf-8") as f:
94- try:
95- meta = json.load(f)
96- except Exception as e:
97- print(f"[WARN] Cannot parse {meta_path}: {e}")
98- continue
99-
100- app_id = meta.get("id")
101- name = meta.get("name", app_id)
102- description = meta.get("description", "")
103- screenshot_rel = meta.get("screenshot")
104-
105- # Only support multi dist directories; ignore legacy single distDir
106- dist_dirs_rel = meta.get("distDirs", []) if isinstance(meta.get("distDirs"), list) else []
107-
108- if not app_id:
109- print(f"[WARN] {meta_path} missing 'id', skipping.")
110- continue
111-
112- # If no distDirs provided, just register app for index but skip copy
113- if not dist_dirs_rel:
114- print(f"[INFO] {meta_path} has no 'distDirs'; will only list app on index (no files copied).")
115-
116- project_root = dirpath
117-
118- # Helper: merge-copy contents of src into dst (overwrite on conflicts)
119- def merge_copy(src: str, dst: str):
120- if not os.path.exists(src):
121- return
122- os.makedirs(dst, exist_ok=True)
123- for name in os.listdir(src):
124- s = os.path.join(src, name)
125- d = os.path.join(dst, name)
126- if os.path.isdir(s):
127- merge_copy(s, d)
128- else:
129- os.makedirs(os.path.dirname(d), exist_ok=True)
130- try:
131- shutil.copy2(s, d)
132- except Exception as e:
133- print(f"[WARN] Failed to copy {s} -> {d}: {e}")
134-
135- # Copy contents of every configured distDir into site/<id>/ (no validation)
136- target_app_dir = os.path.join(SITE_DIR, app_id)
137- if os.path.exists(target_app_dir):
138- shutil.rmtree(target_app_dir)
139- os.makedirs(target_app_dir, exist_ok=True)
140-
141- for rel in dist_dirs_rel:
142- src_dir = os.path.join(project_root, rel)
143- if not os.path.exists(src_dir):
144- print(f"[INFO] distDir does not exist (skipped): {src_dir}")
145- continue
146- print(f"[OK] Merging distDir for {app_id}: {src_dir} -> {target_app_dir}")
147- merge_copy(src_dir, target_app_dir)
148-
149- screenshot_target = None
150- if screenshot_rel:
151- screenshot_src = os.path.join(project_root, screenshot_rel)
152- if os.path.exists(screenshot_src):
153- screenshot_name = os.path.basename(screenshot_src)
154- screenshot_target = f"{app_id}/{screenshot_name}"
155- shutil.copy2(screenshot_src, os.path.join(target_app_dir, screenshot_name))
156- else:
157- print(f"[WARN] Screenshot configured but not found: {screenshot_src}")
158-
159- apps.append({
160- "id": app_id,
161- "name": name or app_id,
162- "description": description,
163- "screenshot": screenshot_target
164- })
165-
166- # Generate root index.html
167- apps.sort(key=lambda a: a["id"])
168- index_html_path = os.path.join(SITE_DIR, "index.html")
169-
170- with open(index_html_path, "w", encoding="utf-8") as f:
171- f.write("<!DOCTYPE html>\n<html lang='en'>\n<head>\n")
172- f.write(" <meta charset='UTF-8'>\n")
173- f.write(" <meta name='viewport' content='width=device-width, initial-scale=1.0'>\n")
174- f.write(" <title>KMP Web Apps</title>\n")
175- f.write(" <style>\n")
176- f.write(" body { font-family: system-ui, sans-serif; max-width: 960px; margin: 2rem auto; padding: 0 1rem; }\n")
177- f.write(" h1 { margin-bottom: 0.25rem; }\n")
178- f.write(" .tag { color: #666; font-size: 0.9rem; margin-bottom: 1.5rem; }\n")
179- f.write(" .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; }\n")
180- f.write(" .card { border: 1px solid #ddd; border-radius: 0.75rem; padding: 1rem; text-decoration: none; color: inherit; background: #fafafa; transition: box-shadow 0.15s, transform 0.15s; }\n")
181- f.write(" .card:hover { box-shadow: 0 6px 18px rgba(0,0,0,0.08); transform: translateY(-2px); }\n")
182- f.write(" .card h2 { margin-top: 0; margin-bottom: 0.25rem; font-size: 1.1rem; }\n")
183- f.write(" .card p { margin: 0.25rem 0 0.5rem 0; font-size: 0.9rem; color: #555; }\n")
184- f.write(" .badge { display: inline-block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: #555; background: #eaeaea; padding: 0.1rem 0.45rem; border-radius: 999px; margin-bottom: 0.3rem; }\n")
185- f.write(" .screenshot { width: 100%; border-radius: 0.5rem; margin-top: 0.5rem; border: 1px solid #e0e0e0; object-fit: cover; max-height: 180px; }\n")
186- f.write(" .empty { color: #777; font-style: italic; }\n")
187- f.write(" </style>\n")
188- f.write("</head>\n<body>\n")
189-
190- f.write(" <h1>KMP Web Apps</h1>\n")
191- if release_tag:
192- f.write(f" <div class='tag'>Deployed from release <strong>{html.escape(release_tag)}</strong></div>\n")
193-
194- if not apps:
195- f.write(" <p class='empty'>No web apps detected for this release (no valid <code>webapp.json</code> with a working <code>index.html</code>).</p>\n")
196- else:
197- f.write(" <div class='grid'>\n")
198- for app in apps:
199- href = f"./{app['id']}/"
200- name = html.escape(app["name"])
201- desc = html.escape(app["description"] or "")
202- f.write(f" <a class='card' href='{href}'>\n")
203- f.write(f" <div class='badge'>/{html.escape(app['id'])}</div>\n")
204- f.write(f" <h2>{name}</h2>\n")
205- if desc:
206- f.write(f" <p>{desc}</p>\n")
207- if app["screenshot"]:
208- f.write(f" <img class='screenshot' src='{html.escape(app['screenshot'])}' alt='Screenshot of {name}' />\n")
209- f.write(" </a>\n")
210- f.write(" </div>\n")
211-
212- f.write("</body>\n</html>\n")
213-
214- print(f"[OK] Root index generated at {index_html_path}")
215- PYTHON_EOF
72+ python3 scripts/generate-samples-page.py --build --output site
21673
21774 - name : Upload artifact for GitHub Pages
21875 uses : actions/upload-pages-artifact@v3
0 commit comments