feat: sync extensions.description from manifest.json
Manifest is now the source of truth for the catalog label shown in the admin UI. build_and_publish updates description on every release; the new _sync_description_from_manifest helper is also called from sync_extension_registry for backfill / drift correction (runs every 6h via the auto-add-webhook workflow, or on manual /sync-registry). This replaces the hardcoded HEBREW_LABELS map in KlearBranding's admin/index.js — new extensions inherit their label from their manifest without code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -166,6 +166,12 @@ def sync_extension_registry():
|
||||
) sub WHERE e.id = sub.extension_id AND (e.latest_version IS NULL OR e.latest_version != sub.max_ver)""",
|
||||
fetch=None)
|
||||
|
||||
# Sync description from each extension's manifest.json (main branch) — manifest is source of truth for the catalog label
|
||||
description_updates = []
|
||||
for name in gitea_extensions:
|
||||
if _sync_description_from_manifest(name):
|
||||
description_updates.append(name)
|
||||
|
||||
# Reload MODULES from DB
|
||||
_load_modules_from_db()
|
||||
|
||||
@@ -173,9 +179,31 @@ def sync_extension_registry():
|
||||
'status': 'ok',
|
||||
'gitea_extensions': len(gitea_extensions),
|
||||
'added': added, 'reactivated': reactivated, 'deactivated': deactivated,
|
||||
'description_updates': description_updates,
|
||||
'active_modules': sorted(MODULES.keys())
|
||||
}
|
||||
|
||||
|
||||
def _sync_description_from_manifest(module):
|
||||
"""Fetch manifest.json from the extension's Gitea main branch and update extensions.description.
|
||||
Returns True if the description was changed."""
|
||||
resp = gitea_api('GET', f'/repos/{GITEA_ORG}/{module}/contents/manifest.json')
|
||||
if not isinstance(resp, dict) or not resp.get('content'):
|
||||
return False
|
||||
try:
|
||||
manifest = json.loads(base64.b64decode(resp['content']))
|
||||
except Exception:
|
||||
return False
|
||||
desc = (manifest.get('description') or '').strip()
|
||||
if not desc:
|
||||
return False
|
||||
current = query("SELECT description FROM extensions WHERE name = %s", (module,), fetch='one')
|
||||
if current and (current.get('description') or '').strip() == desc:
|
||||
return False
|
||||
query("UPDATE extensions SET description = %s, updated_at = NOW() WHERE name = %s",
|
||||
(desc, module), fetch=None)
|
||||
return True
|
||||
|
||||
SSL_CTX = ssl.create_default_context()
|
||||
SSL_CTX.check_hostname = False
|
||||
SSL_CTX.verify_mode = ssl.CERT_NONE
|
||||
@@ -376,6 +404,10 @@ def build_and_publish(module, version):
|
||||
cur.execute("""UPDATE extensions SET latest_version = %s, updated_at = NOW()
|
||||
WHERE name = %s AND (latest_version IS NULL OR string_to_array(latest_version, '.')::int[] < string_to_array(%s, '.')::int[])""",
|
||||
(version, module, version))
|
||||
manifest_desc = (manifest.get('description') or '').strip()
|
||||
if manifest_desc:
|
||||
cur.execute("UPDATE extensions SET description = %s, updated_at = NOW() WHERE name = %s",
|
||||
(manifest_desc, module))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
Reference in New Issue
Block a user