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)""",
|
) sub WHERE e.id = sub.extension_id AND (e.latest_version IS NULL OR e.latest_version != sub.max_ver)""",
|
||||||
fetch=None)
|
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
|
# Reload MODULES from DB
|
||||||
_load_modules_from_db()
|
_load_modules_from_db()
|
||||||
|
|
||||||
@@ -173,9 +179,31 @@ def sync_extension_registry():
|
|||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
'gitea_extensions': len(gitea_extensions),
|
'gitea_extensions': len(gitea_extensions),
|
||||||
'added': added, 'reactivated': reactivated, 'deactivated': deactivated,
|
'added': added, 'reactivated': reactivated, 'deactivated': deactivated,
|
||||||
|
'description_updates': description_updates,
|
||||||
'active_modules': sorted(MODULES.keys())
|
'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 = ssl.create_default_context()
|
||||||
SSL_CTX.check_hostname = False
|
SSL_CTX.check_hostname = False
|
||||||
SSL_CTX.verify_mode = ssl.CERT_NONE
|
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()
|
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[])""",
|
WHERE name = %s AND (latest_version IS NULL OR string_to_array(latest_version, '.')::int[] < string_to_array(%s, '.')::int[])""",
|
||||||
(version, module, version))
|
(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()
|
conn.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|||||||
Reference in New Issue
Block a user