feat: Enhance community stats workflow to detect plugin version changes and robustly extract plugin data in the generation script.

This commit is contained in:
fujie
2026-03-11 23:45:21 +08:00
parent fdf95a2825
commit 93a42cbe03
2 changed files with 47 additions and 11 deletions

View File

@@ -38,9 +38,12 @@ jobs:
id: old_stats
run: |
if [ -f docs/community-stats.json ]; then
cp docs/community-stats.json docs/community-stats.json.old
echo "total_posts=$(jq -r '.total_posts // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "versions=$(jq -r '[.posts[] | {slug: .slug, version: .version}] | sort_by(.slug) | map("\(.slug):\(.version)") | join(",")' docs/community-stats.json)" >> $GITHUB_OUTPUT
else
echo "total_posts=0" >> $GITHUB_OUTPUT
echo "versions=" >> $GITHUB_OUTPUT
fi
- name: Generate stats report
@@ -56,12 +59,15 @@ jobs:
id: new_stats
run: |
echo "total_posts=$(jq -r '.total_posts // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "versions=$(jq -r '[.posts[] | {slug: .slug, version: .version}] | sort_by(.slug) | map("\(.slug):\(.version)") | join(",")' docs/community-stats.json)" >> $GITHUB_OUTPUT
- name: Check for significant changes
id: check_changes
run: |
OLD_POSTS="${{ steps.old_stats.outputs.total_posts }}"
NEW_POSTS="${{ steps.new_stats.outputs.total_posts }}"
OLD_VERSIONS="${{ steps.old_stats.outputs.versions }}"
NEW_VERSIONS="${{ steps.new_stats.outputs.versions }}"
SHOULD_COMMIT="false"
CHANGE_REASON=""
@@ -69,14 +75,20 @@ jobs:
if [ "$NEW_POSTS" -gt "$OLD_POSTS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="new plugin added ($OLD_POSTS -> $NEW_POSTS)"
echo "📦 New plugin detected: $OLD_POSTS -> $NEW_POSTS"
elif [ "$NEW_POSTS" -lt "$OLD_POSTS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="plugin removed ($OLD_POSTS -> $NEW_POSTS)"
elif [ "$OLD_VERSIONS" != "$NEW_VERSIONS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="plugin versions updated"
echo "🔄 Version change detected"
fi
echo "should_commit=$SHOULD_COMMIT" >> $GITHUB_OUTPUT
echo "change_reason=$CHANGE_REASON" >> $GITHUB_OUTPUT
if [ "$SHOULD_COMMIT" = "false" ]; then
echo " No significant changes detected, skipping commit"
echo " No significant changes (posts or versions), skipping commit"
else
echo "✅ Significant changes detected: $CHANGE_REASON"
fi

View File

@@ -277,12 +277,37 @@ class OpenWebUIStats:
},
}
def _get_plugin_obj(self, post: dict) -> dict:
"""Extract the actual plugin object from post['data'] (handling different keys like function/tool/pipe)."""
data = post.get("data", {}) or {}
if not data:
return {}
# Priority 1: Use post['type'] as the key (standard behavior)
post_type = post.get("type")
if post_type and post_type in data and data[post_type]:
return data[post_type]
# Priority 2: Fallback to 'function' (most common for actions/filters/pipes)
if "function" in data and data["function"]:
return data["function"]
# Priority 3: Try other known keys
for k in ["tool", "pipe", "action", "filter", "prompt", "model"]:
if k in data and data[k]:
return data[k]
# Priority 4: If there's only one key in data, assume that's the one
if len(data) == 1:
return list(data.values())[0] or {}
return {}
def _resolve_post_type(self, post: dict) -> str:
"""Resolve the post category type"""
top_type = post.get("type")
function_data = post.get("data", {}) or {}
function_obj = function_data.get("function", {}) or {}
meta = function_obj.get("meta", {}) or {}
plugin_obj = self._get_plugin_obj(post)
meta = plugin_obj.get("meta", {}) or {}
manifest = meta.get("manifest", {}) or {}
# Category identification priority:
@@ -292,8 +317,8 @@ class OpenWebUIStats:
post_type = "unknown"
if meta.get("type"):
post_type = meta.get("type")
elif function_obj.get("type"):
post_type = function_obj.get("type")
elif plugin_obj.get("type"):
post_type = plugin_obj.get("type")
elif top_type:
post_type = top_type
elif not meta and not function_obj:
@@ -302,7 +327,7 @@ class OpenWebUIStats:
post_type = self._normalize_post_type(post_type)
# Unified and heuristic identification logic
if post_type == "unknown" and function_obj:
if post_type == "unknown" and plugin_obj:
post_type = "action"
if post_type == "action" or post_type == "unknown":
@@ -600,9 +625,8 @@ class OpenWebUIStats:
for post in posts:
post_type = self._resolve_post_type(post)
function_data = post.get("data", {}) or {}
function_obj = function_data.get("function", {}) or {}
meta = function_obj.get("meta", {}) or {}
plugin_obj = self._get_plugin_obj(post)
meta = plugin_obj.get("meta", {}) or {}
manifest = meta.get("manifest", {}) or {}
# Accumulate statistics